diff --git a/app/Models/InvoiceItem.php b/app/Models/InvoiceItem.php
index 8fee3a8..6d34d16 100644
--- a/app/Models/InvoiceItem.php
+++ b/app/Models/InvoiceItem.php
@@ -4,6 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
+use Leenooks\Carbon;
class InvoiceItem extends Model
{
@@ -36,6 +37,36 @@ class InvoiceItem extends Model
/** ATTRIBUTES **/
+ /**
+ * Start date for the invoice item line
+ *
+ * We need cast this value to a Leenooks\Carbon for access to startOfHalf() endOfHalf() methods
+ *
+ * @param $value
+ * @return Carbon
+ * @throws \Exception
+ */
+ public function getDateStartAttribute($value)
+ {
+ if (! is_null($value))
+ return Carbon::createFromTimestamp($value);
+ }
+
+ /**
+ * End date for the invoice item line
+ *
+ * We need cast this value to a Leenooks\Carbon for access to startOfHalf() endOfHalf() methods
+ *
+ * @param $value
+ * @return Carbon
+ * @throws \Exception
+ */
+ public function getDateStopAttribute($value)
+ {
+ if (! is_null($value))
+ return Carbon::createFromTimestamp($value);
+ }
+
public function getItemTypeNameAttribute()
{
$types = [
diff --git a/app/Models/Service.php b/app/Models/Service.php
index ff67990..2cd7cfc 100644
--- a/app/Models/Service.php
+++ b/app/Models/Service.php
@@ -2,15 +2,18 @@
namespace App\Models;
-use Illuminate\Database\Eloquent\Collection;
+use Exception;
+use Illuminate\Database\Eloquent\Collection as DatabaseCollection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Support\Arr;
+use Illuminate\Support\Collection;
use App\Traits\NextKey;
+use Leenooks\Carbon;
class Service extends Model
{
@@ -23,8 +26,11 @@ class Service extends Model
protected $dates = [
'date_last_invoice',
- 'date_next_invoice'
+ 'date_next_invoice'.
+ 'date_start',
+ 'date_end',
];
+
public $dateFormat = 'U';
protected $table = 'ab_service';
@@ -303,38 +309,124 @@ class Service extends Model
* Return the date for the next invoice
*
* @todo This function negates the need for date_next_invoice
- * @return null
+ * @return Carbon|string
*/
public function getInvoiceNextAttribute()
{
$last = $this->getInvoiceToAttribute();
- $date = $last ? $last->addDay() : now();
+ $date = $last ? $last->addDay() : Carbon::now();
return request()->wantsJson() ? $date->format('Y-m-d') : $date;
}
+ /**
+ * Return the end date for the next invoice
+ *
+ * @return mixed
+ * @throws Exception
+ */
public function getInvoiceNextEndAttribute()
{
- switch ($this->recur_schedule)
- {
+ switch ($this->recur_schedule) {
// Weekly
- case 0: $date = $this->getInvoiceNextAttribute()->addWeek(); break;
+ case 0: $date = $this->product->price_recurr_strict
+ ? $this->getInvoiceNextAttribute()->endOfWeek()
+ : $this->getInvoiceNextAttribute()->addWeek()->subDay();
+ break;
+
// Monthly
- case 1: $date = $this->getInvoiceNextAttribute()->addMonth(); break;
+ case 1:
+ $date = $this->product->price_recurr_strict
+ ? $this->getInvoiceNextAttribute()->endOfMonth()
+ : $this->getInvoiceNextAttribute()->addMonth()->subDay();
+ break;
+
// Quarterly
- case 2: $date = $this->getInvoiceNextAttribute()->addQuarter(); break;
+ case 2:
+ $date = $this->product->price_recurr_strict
+ ? $this->getInvoiceNextAttribute()->endOfQuarter()
+ : $this->getInvoiceNextAttribute()->addQuarter()->subDay();
+ break;
+
// Half Yearly
- case 3: $date = $this->getInvoiceNextAttribute()->addQuarter(2); break;
+ case 3:
+ $date = $this->product->price_recurr_strict
+ ? $this->getInvoiceNextAttribute()->endOfHalf()
+ : $this->getInvoiceNextAttribute()->addQuarter(2)->subDay();
+ break;
+
// Yearly
- case 4: $date = $this->getInvoiceNextAttribute()->addYear(); break;
+ case 4:
+ $date = $this->product->price_recurr_strict
+ ? $this->getInvoiceNextAttribute()->endOfYear()
+ : $this->getInvoiceNextAttribute()->addYear()->subDay();
+ break;
+
// Two Yearly
- case 5: $date = $this->getInvoiceNextAttribute()->addYear(2); break;
+ // NOTE: price_recurr_strict ignored
+ case 5: $date = $this->getInvoiceNextAttribute()->addYear(2)->subDay(); break;
+
// Three Yearly
- case 6: $date = $this->getInvoiceNextAttribute()->addYear(3); break;
- default: throw new \Exception('Unknown recur_schedule');
+ // NOTE: price_recurr_strict ignored
+ case 6: $date = $this->getInvoiceNextAttribute()->addYear(3)->subDay(); break;
+
+ default: throw new Exception('Unknown recur_schedule');
}
- return $date->subDay();
+ return $date;
+ }
+
+ public function getInvoiceNextQuantityAttribute()
+ {
+ // If we are not rounding to the first day of the cycle, then it is always a full cycle
+ if (! $this->product->price_recurr_strict)
+ return 1;
+
+ $n = $this->invoice_next->diff($this->invoice_next_end)->days+1;
+
+ switch ($this->recur_schedule) {
+ // Weekly
+ case 0:
+ $d = $this->invoice_next_end->diff($this->invoice_next_end->startOfWeek())->days;
+ break;
+
+ // Monthly
+ case 1:
+ $d = $this->invoice_next_end->diff($this->invoice_next_end->startOfMonth())->days;
+ break;
+
+ // Quarterly
+ case 2:
+ $d = $this->invoice_next_end->diff($this->invoice_next_end->startOfQuarter())->days;
+ break;
+
+ // Half Yearly
+ case 3:
+ $d = $this->invoice_next_end->diff($this->invoice_next_end->startOfHalf())->days;
+ break;
+
+ // Yearly
+ case 4:
+ $d = $this->invoice_next_end->diff($this->invoice_next_end->startOfYear())->days;
+ break;
+
+ // Two Yearly
+ case 5:
+ $d = $this->invoice_next_end->diff($this->invoice_next_end->subyear(2))->days-1;
+ break;
+
+ // Three Yearly
+ case 6:
+ $d = $this->invoice_next_end->diff($this->invoice_next_end->subyear(3))->days-1;
+ break;
+
+ default: throw new Exception('Unknown recur_schedule');
+ }
+
+ // Include the start date and end date.
+ $d += 1;
+
+ return round($n/$d,2);
}
/**
@@ -541,14 +633,24 @@ class Service extends Model
public function getStatusHTMLAttribute(): string
{
$class = NULL;
- switch ($this->status)
- {
- case 'ACTIVE':
- $class = 'badge-success';
- break;
- }
- return sprintf('%s',$class,$this->status);
+ if ($this->isPending())
+ $class = 'badge-warning';
+
+ else
+ switch ($this->status)
+ {
+ case 'ACTIVE':
+ $class = 'badge-success';
+ break;
+ case 'INACTIVE':
+ $class = 'badge-danger';
+ break;
+ }
+
+ return $class
+ ? sprintf('%s',$class,$this->status)
+ : $this->status;
}
/**
@@ -597,7 +699,7 @@ class Service extends Model
return round($value*1.1,2);
}
- public function invoices_due(): Collection
+ public function invoices_due(): DatabaseCollection
{
$this->load('invoice_items.invoice');
@@ -635,29 +737,41 @@ class Service extends Model
*/
public function isPending(): bool
{
- return ! $this->active AND ! in_array($this->order_status,$this->inactive_status);
+ return ! $this->active
+ AND ! is_null($this->order_status)
+ AND ! in_array($this->order_status,array_merge($this->inactive_status,['INACTIVE']));
}
- public function next_invoice_items(): \Illuminate\Support\Collection
+ /**
+ * Generate a collection of invoice_item objects that will be billed for the next invoice
+ *
+ * @return Collection
+ * @throws Exception
+ */
+ public function next_invoice_items(): Collection
{
$result = collect();
$o = new InvoiceItem;
- $o->active = TRUE;
- $o->service_id = $this->id;
- $o->product_id = $this->product_id;
- $o->quantity = 1;
- $o->item_type = 0;
- $o->price_base = $this->price ?: $this->product->price($this->recur_schedule); // @todo change to a method in this class
- $o->recurring_schedule = $this->recur_schedule;
- $o->date_start = $this->invoice_next;
- $o->date_stop = $this->invoice_next_end;
- $o->addTaxes();
- $result->push($o);
+ // If the service is active, there will be service charges
+ if ($this->active or $this->isPending()) {
+ $o->active = TRUE;
+ $o->service_id = $this->id;
+ $o->product_id = $this->product_id;
+ $o->item_type = 0;
+ $o->price_base = $this->price ?: $this->product->price($this->recur_schedule); // @todo change to a method in this class
+ $o->recurring_schedule = $this->recur_schedule;
+ $o->date_start = $this->invoice_next;
+ $o->date_stop = $this->invoice_next_end;
+ $o->quantity = $this->invoice_next_quantity;
- foreach ($this->charges->filter(function($item) { return ! $item->processed; }) as $oo)
- {
+ $o->addTaxes();
+ $result->push($o);
+ }
+
+ // Add additional charges
+ foreach ($this->charges->filter(function($item) { return ! $item->processed; }) as $oo) {
$o = new InvoiceItem;
$o->active = TRUE;
$o->service_id = $oo->service_id;
diff --git a/database/factories/InvoiceItemFactory.php b/database/factories/InvoiceItemFactory.php
new file mode 100644
index 0000000..b79e84c
--- /dev/null
+++ b/database/factories/InvoiceItemFactory.php
@@ -0,0 +1,77 @@
+define(App\Models\InvoiceItem::class, function (Faker $faker) {
+ return [
+ 'id'=>1,
+ ];
+});
+
+// Weekly
+$factory->state(App\Models\InvoiceItem::class,'week',[
+ 'date_start'=>Carbon::now()->startOfWeek(),
+ 'date_stop'=>Carbon::now()->endOfWeek(),
+]);
+
+$factory->state(App\Models\InvoiceItem::class,'week-mid',[
+ 'date_start'=>Carbon::now()->startOfWeek(),
+ 'date_stop'=>Carbon::now()->endOfWeek()->addDays(3),
+]);
+
+// Monthly
+$factory->state(App\Models\InvoiceItem::class,'month',[
+ 'date_start'=>Carbon::now()->startOfMonth(),
+ 'date_stop'=>Carbon::now()->endOfMonth(),
+]);
+
+$factory->state(App\Models\InvoiceItem::class,'month-mid',[
+ 'date_start'=>Carbon::now()->startOfMonth(),
+ 'date_stop'=>Carbon::now()->endOfMonth()->addDays(Carbon::now()->daysInMonth/2+1),
+]);
+
+// Quarterly
+$factory->state(App\Models\InvoiceItem::class,'quarter',[
+ 'date_start'=>Carbon::now()->startOfQuarter(),
+ 'date_stop'=>Carbon::now()->endOfQuarter(),
+]);
+
+$factory->state(App\Models\InvoiceItem::class,'quarter-mid',[
+ 'date_start'=>Carbon::now()->startOfQuarter(),
+ 'date_stop'=>Carbon::now()->startOfQuarter()->addDays(45),
+]);
+
+// Half Yearly
+$factory->state(App\Models\InvoiceItem::class,'half',[
+ 'date_start'=>Carbon::now()->startOfHalf(),
+ 'date_stop'=>Carbon::now()->endOfHalf(),
+]);
+
+$factory->state(App\Models\InvoiceItem::class,'half-mid',[
+ 'date_start'=>Carbon::now()->startOfHalf(),
+ 'date_stop'=>Carbon::now()->startOfHalf()->addDays(90),
+]);
+
+// Yearly
+$factory->state(App\Models\InvoiceItem::class,'year',[
+ 'date_start'=>Carbon::now()->startOfYear(),
+ 'date_stop'=>Carbon::now()->endOfYear(),
+]);
+
+$factory->state(App\Models\InvoiceItem::class,'year-mid',[
+ 'date_start'=>Carbon::now()->startOfYear(),
+ 'date_stop'=>Carbon::now()->startOfYear()->addDays(181),
+]);
+
+// Two Yearly (price_recurr_strict ignored)
+$factory->state(App\Models\InvoiceItem::class,'2year',[
+ 'date_start'=>Carbon::now()->subyear(),
+ 'date_stop'=>Carbon::now()->subday(),
+]);
+
+// Three Yearly (price_recurr_strict ignored)
+$factory->state(App\Models\InvoiceItem::class,'3year',[
+ 'date_start'=>Carbon::now()->subyear(2),
+ 'date_stop'=>Carbon::now()->subday(),
+]);
\ No newline at end of file
diff --git a/database/factories/ProductFactory.php b/database/factories/ProductFactory.php
new file mode 100644
index 0000000..817b81f
--- /dev/null
+++ b/database/factories/ProductFactory.php
@@ -0,0 +1,19 @@
+define(App\Models\Product::class, function (Faker $faker) {
+ return [
+ 'id'=>1,
+ ];
+});
+
+$factory->state(App\Models\Product::class,'active',[
+ 'active' => '1',
+]);
+$factory->state(App\Models\Product::class,'strict',[
+ 'price_recurr_strict' => '1',
+]);
+$factory->state(App\Models\Product::class,'notstrict',[
+ 'price_recurr_strict' => '0',
+]);
\ No newline at end of file
diff --git a/database/factories/ServiceFactory.php b/database/factories/ServiceFactory.php
new file mode 100644
index 0000000..a7002d6
--- /dev/null
+++ b/database/factories/ServiceFactory.php
@@ -0,0 +1,95 @@
+define(App\Models\Service::class, function (Faker $faker) {
+ return [
+ 'account_id'=>1,
+ ];
+});
+
+$factory->afterMaking(App\Models\Service::class, function ($service,$faker) {
+ $product = factory(App\Models\Product::class)->make();
+
+ $service->setRelation('product',$product);
+ $service->product_id = $product->id;
+});
+
+// Weekly
+$factory->afterMakingState(App\Models\Service::class,'week',function ($service,$faker) {
+ $invoice_items = factory(App\Models\InvoiceItem::class,1)->state('week')->make();
+ $service->setRelation('invoice_items',$invoice_items);
+ $service->recur_schedule = 0;
+});
+
+$factory->afterMakingState(App\Models\Service::class,'week-mid',function ($service,$faker) {
+ $invoice_items = factory(App\Models\InvoiceItem::class,1)->state('week-mid')->make();
+ $service->setRelation('invoice_items',$invoice_items);
+ $service->recur_schedule = 0;
+});
+
+// Monthly
+$factory->afterMakingState(App\Models\Service::class,'month',function ($service,$faker) {
+ $invoice_items = factory(App\Models\InvoiceItem::class,1)->state('month')->make();
+ $service->setRelation('invoice_items',$invoice_items);
+ $service->recur_schedule = 1;
+});
+
+$factory->afterMakingState(App\Models\Service::class,'month-mid',function ($service,$faker) {
+ $invoice_items = factory(App\Models\InvoiceItem::class,1)->state('month-mid')->make();
+ $service->setRelation('invoice_items',$invoice_items);
+ $service->recur_schedule = 1;
+});
+
+// Quarterly
+$factory->afterMakingState(App\Models\Service::class,'quarter',function ($service,$faker) {
+ $invoice_items = factory(App\Models\InvoiceItem::class,1)->state('quarter')->make();
+ $service->setRelation('invoice_items',$invoice_items);
+ $service->recur_schedule = 2;
+});
+
+$factory->afterMakingState(App\Models\Service::class,'quarter-mid',function ($service,$faker) {
+ $invoice_items = factory(App\Models\InvoiceItem::class,1)->state('quarter-mid')->make();
+ $service->setRelation('invoice_items',$invoice_items);
+ $service->recur_schedule = 2;
+});
+
+// Half Yearly
+$factory->afterMakingState(App\Models\Service::class,'half',function ($service,$faker) {
+ $invoice_items = factory(App\Models\InvoiceItem::class,1)->state('half')->make();
+ $service->setRelation('invoice_items',$invoice_items);
+ $service->recur_schedule = 3;
+});
+
+$factory->afterMakingState(App\Models\Service::class,'half-mid',function ($service,$faker) {
+ $invoice_items = factory(App\Models\InvoiceItem::class,1)->state('half-mid')->make();
+ $service->setRelation('invoice_items',$invoice_items);
+ $service->recur_schedule = 3;
+});
+
+// Yearly
+$factory->afterMakingState(App\Models\Service::class,'year',function ($service,$faker) {
+ $invoice_items = factory(App\Models\InvoiceItem::class,1)->state('year')->make();
+ $service->setRelation('invoice_items',$invoice_items);
+ $service->recur_schedule = 4;
+});
+
+$factory->afterMakingState(App\Models\Service::class,'year-mid',function ($service,$faker) {
+ $invoice_items = factory(App\Models\InvoiceItem::class,1)->state('year-mid')->make();
+ $service->setRelation('invoice_items',$invoice_items);
+ $service->recur_schedule = 4;
+});
+
+// 2 Yearly
+$factory->afterMakingState(App\Models\Service::class,'2year',function ($service,$faker) {
+ $invoice_items = factory(App\Models\InvoiceItem::class,1)->state('2year')->make();
+ $service->setRelation('invoice_items',$invoice_items);
+ $service->recur_schedule = 5;
+});
+
+// 3 Yearly
+$factory->afterMakingState(App\Models\Service::class,'3year',function ($service,$faker) {
+ $invoice_items = factory(App\Models\InvoiceItem::class,1)->state('3year')->make();
+ $service->setRelation('invoice_items',$invoice_items);
+ $service->recur_schedule = 6;
+});
\ No newline at end of file
diff --git a/resources/theme/backend/adminlte/common/service/widget/invoice.blade.php b/resources/theme/backend/adminlte/common/service/widget/invoice.blade.php
index fcb1421..f3a7e2f 100644
--- a/resources/theme/backend/adminlte/common/service/widget/invoice.blade.php
+++ b/resources/theme/backend/adminlte/common/service/widget/invoice.blade.php
@@ -1,19 +1,13 @@
-
-
+
+
+ {{ $o->name }} | ${{ number_format($o->next_invoice_items()->sum('total'),2) }} |
+
-
-
-
- {{ $o->name }} | ${{ number_format($o->next_invoice_items()->sum('total'),2) }} |
-
-
- @foreach ($o->next_invoice_items() as $io)
-
- | {{ $io->item_type_name }} | ${{ number_format($io->total,2) }} |
-
- @endforeach
-
-
-
\ No newline at end of file
+ @foreach ($o->next_invoice_items() as $io)
+
+ |
+ {{ $io->item_type_name }} |
+ ${{ number_format($io->total,2) }} |
+
+ @endforeach
+
\ No newline at end of file
diff --git a/resources/theme/backend/adminlte/u/service.blade.php b/resources/theme/backend/adminlte/u/service.blade.php
index e3c4636..e0f9c4b 100644
--- a/resources/theme/backend/adminlte/u/service.blade.php
+++ b/resources/theme/backend/adminlte/u/service.blade.php
@@ -8,7 +8,7 @@
@endsection
@section('contentheader_title')
- Service: {{ $o->sid }}
NBN-50/20-100
+ Service: {{ $o->sid }}
{{ $o->product->name }}
@endsection
@section('contentheader_description')
{{ $o->sname }}: {{ $o->sdesc }}
@@ -34,20 +34,22 @@
Emails
-
+ @can('update',$o)
+
+ @endcan
@@ -59,7 +61,7 @@
Product.
- Invoice Next.
+ @include('common.service.widget.invoice')
Invoices.
diff --git a/resources/theme/backend/adminlte/u/service/widgets/broadband/details.blade.php b/resources/theme/backend/adminlte/u/service/widgets/broadband/details.blade.php
index 263c48f..ed9141c 100644
--- a/resources/theme/backend/adminlte/u/service/widgets/broadband/details.blade.php
+++ b/resources/theme/backend/adminlte/u/service/widgets/broadband/details.blade.php
@@ -1,11 +1,10 @@
-
@if($o->service->isPending())
-
-
@endif
\ No newline at end of file
diff --git a/resources/theme/backend/adminlte/u/widgets/service/info.blade.php b/resources/theme/backend/adminlte/u/widgets/service/info.blade.php
deleted file mode 100644
index cd25165..0000000
--- a/resources/theme/backend/adminlte/u/widgets/service/info.blade.php
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
- Account | {{ $o->account->company }} |
-
-
- Active | {{ $o->active }} ({{ $o->order_status }}) [{{ $o->status }}] |
-
-
- Type | {{ $o->type->type }} |
-
-
- Product | {{ $o->product->name }}: {{ $o->name }} |
-
-
- Billing Period | {{ $o->recur_schedule }} |
-
-
- Billing Amount | {{ $o->cost }} |
-
-
- Last Invoice | {{ $o->date_last_invoice }} |
-
-
- Paid Until | {{ 'TBA' }} |
-
-
- Next Invoice | {{ $o->date_next_invoice }} |
-
-
-
-
-
- {{--
-
- --}}
-
\ No newline at end of file
diff --git a/resources/theme/backend/adminlte/u/widgets/service/order/sent.blade.php b/resources/theme/backend/adminlte/u/widgets/service/order/sent.blade.php
deleted file mode 100644
index 5b75791..0000000
--- a/resources/theme/backend/adminlte/u/widgets/service/order/sent.blade.php
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
-
-
- Account | {{ $o->account->company }} |
-
-
- Product | {{ $o->product->name }}: {{ $o->name }} |
-
- @if($o->date_last_invoice)
-
- Last Invoice | {{ $o->date_last_invoice }} |
-
-
- Paid Until | {{ 'TBA' }} |
-
-
- Next Invoice | {{ $o->date_next_invoice }} |
-
- @endif
-
- Ordered | {{ $o->date_orig->format('Y-m-d') }} |
-
- @if ($o->date_last)
-
- Update | {{ $o->date_last->format('Y-m-d') }} |
-
- @endif
-
- Order Details | {!! $o->order_info_details !!} |
-
-
- Reference: | {{ \Illuminate\Support\Arr::get($o->order_info,'order_reference','') }} |
-
-
-
-
- {{--
-
- --}}
-
\ No newline at end of file
diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php
deleted file mode 100644
index 6eb72b6..0000000
--- a/tests/Feature/ExampleTest.php
+++ /dev/null
@@ -1,21 +0,0 @@
-get('/login');
-
- $response->assertStatus(200);
- }
-}
diff --git a/tests/Feature/ServiceTest.php b/tests/Feature/ServiceTest.php
new file mode 100644
index 0000000..3590cd2
--- /dev/null
+++ b/tests/Feature/ServiceTest.php
@@ -0,0 +1,100 @@
+states('week')->make();
+ $o->setRelation('product',factory(Product::class)->states('notstrict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Weekly Equals 1');
+ $o->setRelation('product',factory(Product::class)->states('strict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Weekly Equals 1');
+
+ $o = factory(Service::class)->states('week-mid')->make();
+ $o->setRelation('product',factory(Product::class)->states('notstrict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Weekly Mid Equals 0.57');
+ $o->setRelation('product',factory(Product::class)->states('strict')->make());
+ $this->assertEquals(0.57,$o->invoice_next_quantity,'Weekly Mid Equals 0.57');
+
+ // Test Monthly Billing
+ $o = factory(Service::class)->states('month')->make();
+ $o->setRelation('product',factory(Product::class)->states('notstrict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Monthly Equals 1');
+ $o->setRelation('product',factory(Product::class)->states('strict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Monthly Equals 1');
+
+ $o = factory(Service::class)->states('month-mid')->make();
+ $o->setRelation('product',factory(Product::class)->states('notstrict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Monthly Equals 1');
+ $o->setRelation('product',factory(Product::class)->states('strict')->make());
+ $this->assertEquals(round(round(Carbon::now()->addMonth()->daysInMonth/2,0)/Carbon::now()->addMonth()->daysInMonth,2),$o->invoice_next_quantity,'Monthly Mid Equals 0.5');
+
+ // Test Quarterly Billing
+ $o = factory(Service::class)->states('quarter')->make();
+ $o->setRelation('product',factory(Product::class)->states('notstrict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Quarterly Equals 1');
+ $o->setRelation('product',factory(Product::class)->states('strict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Quarterly Equals 1');
+
+ $o = factory(Service::class)->states('quarter-mid')->make();
+ $o->setRelation('product',factory(Product::class)->states('notstrict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Quarterly Equals 1');
+ $o->setRelation('product',factory(Product::class)->states('strict')->make());
+ $this->assertEqualsWithDelta(0.5,$o->invoice_next_quantity,.02,'Quarterly Mid Equals 0.5');
+
+ // Test Half Year Billing
+ $o = factory(Service::class)->states('half')->make();
+ $o->setRelation('product',factory(Product::class)->states('notstrict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Half Yearly Equals 1');
+ $o->setRelation('product',factory(Product::class)->states('strict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Half Yearly Equals 1');
+
+ $o = factory(Service::class)->states('half-mid')->make();
+ $o->setRelation('product',factory(Product::class)->states('notstrict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Half Yearly Equals 1');
+ $o->setRelation('product',factory(Product::class)->states('strict')->make());
+ $this->assertEquals(0.5,$o->invoice_next_quantity,'Half Yearly Mid Equals 0.5');
+
+ // Test Year Billing
+ $o = factory(Service::class)->states('year')->make();
+ $o->setRelation('product',factory(Product::class)->states('notstrict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Yearly Equals 1');
+ $o->setRelation('product',factory(Product::class)->states('strict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Yearly Equals 1');
+
+ $o = factory(Service::class)->states('year-mid')->make();
+ $o->setRelation('product',factory(Product::class)->states('notstrict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Yearly Equals 1');
+ $o->setRelation('product',factory(Product::class)->states('strict')->make());
+ $this->assertEquals(0.5,$o->invoice_next_quantity,'Yearly Mid Equals 0.5');
+
+ // Test 2 Year Billing (price_recurr_strict ignored)
+ $o = factory(Service::class)->states('2year')->make();
+ $o->setRelation('product',factory(Product::class)->states('notstrict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Two Yearly Equals 1');
+ $o->setRelation('product',factory(Product::class)->states('strict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Two Yearly Equals 1');
+
+ // Test 3 Year Billing (price_recurr_strict ignored)
+ $o = factory(Service::class)->states('3year')->make();
+ $o->setRelation('product',factory(Product::class)->states('notstrict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Three Yearly Equals 1');
+ $o->setRelation('product',factory(Product::class)->states('strict')->make());
+ $this->assertEquals(1,$o->invoice_next_quantity,'Three Yearly Equals 1');
+ }
+}
\ No newline at end of file
diff --git a/tests/Unit/ExampleTest.php b/tests/Unit/ExampleTest.php
deleted file mode 100644
index e9fe19c..0000000
--- a/tests/Unit/ExampleTest.php
+++ /dev/null
@@ -1,19 +0,0 @@
-assertTrue(true);
- }
-}