Recurring dates

This commit is contained in:
David Bomba 2020-09-14 22:13:15 +10:00
parent bae82b56c1
commit 766343d8b9
3 changed files with 156 additions and 18 deletions

View File

@ -16,6 +16,7 @@ use App\Helpers\Invoice\InvoiceSumInclusive;
use App\Models\Filterable;
use App\Utils\Traits\MakesDates;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\Recurring\HasRecurrence;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
@ -29,6 +30,8 @@ class RecurringInvoice extends BaseModel
use SoftDeletes;
use Filterable;
use MakesDates;
use HasRecurrence;
/**
* Invoice Statuses.
*/
@ -387,7 +390,7 @@ class RecurringInvoice extends BaseModel
'due_date' => $next_due_date->format('Y-m-d'),
];
$next_send_date = $this->nextDateByFrequency($next_send_date);
$next_send_date = $this->calculateDueDate($next_send_date);
}
@ -404,20 +407,15 @@ class RecurringInvoice extends BaseModel
}
private function calculateDueDate($terms, $date)
private function calculateDueDate($date)
{
switch ($terms) {
case 'client_terms':
switch ($this->due_date_days) {
case 'terms':
return $this->calculateDateFromTerms($date);
break;
case 'first_of_month':
return $this->calculateFirstDayOfMonth($date);
break;
case 'last_of_month':
break;
default:
return $this->setDayOfMonth($date, $terms);
return $this->setDayOfMonth($date, $this->due_date_days);
break;
}
}

View File

@ -12,6 +12,7 @@
namespace App\Utils\Traits\Recurring;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
trait HasRecurrence
{
@ -39,7 +40,7 @@ trait HasRecurrence
public function calculateLastDayOfMonth($date)
{
if($date->isLastOfMonth())
return $date->copy()->endOfMonth()->addMonthNoOverflow();
return $date->copy()->addMonthNoOverflow()->endOfMonth();
return $date->copy()->endOfMonth();
}
@ -50,13 +51,19 @@ trait HasRecurrence
* @param Carbon $date The start date
* @param String|Int $day_of_month The day of the month
*/
public function setDateOfMonth($date, $day_of_month)
public function setDayOfMonth($date, $day_of_month)
{
$set_date = $date->copy()->setUnitNoOverflow('day', $day_of_month, 'month');
if($set_date->isPast())
return $set_date->addMonthNoOverflow();
//If the set date is less than the original date we need to add a month.
//If we are overflowing dates, then we need to diff the dates and ensure it doesn't equal 0
if($set_date->lte($date) || $set_date->diffInDays($date) == 0)
$set_date->addMonthNoOverflow();
if($day_of_month == '31')
$set_date->endOfMonth();
return $set_date;
}

View File

@ -24,10 +24,6 @@ class RecurringDueDatesTest extends TestCase
use HasRecurrence;
public function setUp() :void
{
}
public function testFirstDate()
{
@ -37,6 +33,143 @@ class RecurringDueDatesTest extends TestCase
$due_date = $this->calculateFirstDayOfMonth($date);
$this->assertEquals('2020-03-01', $due_date->format('Y-m-d'));
}
public function testFirstOfMonthOnFirst()
{
$date = Carbon::parse('2020-02-01');
$due_date = $this->calculateFirstDayOfMonth($date);
$this->assertEquals('2020-03-01', $due_date->format('Y-m-d'));
}
public function testFirstOfMonthOnLast()
{
$date = Carbon::parse('2020-03-31');
$due_date = $this->calculateFirstDayOfMonth($date);
$this->assertEquals('2020-04-01', $due_date->format('Y-m-d'));
}
public function testLastOfMonth()
{
$date = Carbon::parse('2020-02-15');
$due_date = $this->calculateLastDayOfMonth($date);
$this->assertEquals('2020-02-29', $due_date->format('Y-m-d'));
}
public function testLastOfMonthOnFirst()
{
$date = Carbon::parse('2020-02-1');
$due_date = $this->calculateLastDayOfMonth($date);
$this->assertEquals('2020-02-29', $due_date->format('Y-m-d'));
}
public function testLastOfMonthOnLast()
{
$date = Carbon::parse('2020-02-29');
$due_date = $this->calculateLastDayOfMonth($date);
$this->assertEquals('2020-03-31', $due_date->format('Y-m-d'));
}
public function testDayOfMonth()
{
$date = Carbon::parse('2020-02-01');
$due_date = $this->setDayOfMonth($date, '15');
$this->assertEquals('2020-02-15', $due_date->format('Y-m-d'));
}
public function testDayOfMonthInFuture()
{
$date = Carbon::parse('2020-02-16');
$due_date = $this->setDayOfMonth($date, '15');
$this->assertEquals('2020-03-15', $due_date->format('Y-m-d'));
}
public function testDayOfMonthSameDay()
{
$date = Carbon::parse('2020-02-01');
$due_date = $this->setDayOfMonth($date, '1');
$this->assertEquals('2020-03-01', $due_date->format('Y-m-d'));
}
public function testDayOfMonthWithOverflow()
{
$date = Carbon::parse('2020-1-31');
$due_date = $this->setDayOfMonth($date, '31');
$this->assertEquals('2020-02-29', $due_date->format('Y-m-d'));
}
public function testDayOfMonthWithOverflow2()
{
$date = Carbon::parse('2020-02-29');
$due_date = $this->setDayOfMonth($date, '31');
$this->assertEquals('2020-03-31', $due_date->format('Y-m-d'));
}
public function testDayOfMonthWithOverflow3()
{
$date = Carbon::parse('2020-01-30');
$due_date = $this->setDayOfMonth($date, '30');
$this->assertEquals('2020-02-29', $due_date->format('Y-m-d'));
}
public function testDayOfMonthWithOverflow4()
{
$date = Carbon::parse('2019-02-28');
$due_date = $this->setDayOfMonth($date, '31');
$this->assertEquals('2019-03-31', $due_date->format('Y-m-d'));
}
public function testDayOfMonthWithOverflow5()
{
$date = Carbon::parse('2019-1-31');
$due_date = $this->setDayOfMonth($date, '31');
$this->assertEquals('2019-02-28', $due_date->format('Y-m-d'));
}
}