Skip to content

Commit

Permalink
Recurring Invoices Client Side and Backend Implementation
Browse files Browse the repository at this point in the history
This implementation will allow you to make a recurring invoice standalone
Turn off recurring invoices for a set of invoices
Turn on recurring invoices for an existing invoice
Update future recurring invoices using an existing recurring invoice
  • Loading branch information
zanechua committed Nov 8, 2018
1 parent e3e75fc commit f53665c
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 129 deletions.
108 changes: 74 additions & 34 deletions app/Http/Controllers/InvoiceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ public function store(CreateInvoiceRequest $request)
$invoiceEvent->until_type = $repeatUntilOption;
$invoiceEvent->until_meta = $repeatUntilMeta;
$invoiceEvent->rule = $rruleString;
$invoiceEvent->company_id = $invoice->company_id;
$invoiceEvent->save();

$invoice->invoice_event_id = $invoiceEvent->id;
Expand Down Expand Up @@ -362,7 +363,7 @@ public function edit(Invoice $invoice)
{
$company = auth()->user()->company;
$clients = $company->clients;
$event = ($invoice->event) ? $invoice->event : collect();
$event = ($invoice->event) ? $invoice->event : null;

return view('pages.invoice.edit', compact('invoice', 'clients', 'event'));
}
Expand Down Expand Up @@ -439,26 +440,40 @@ public function update(UpdateInvoiceRequest $request, Invoice $invoice)
}

$invoice = $invoice->fresh();

$invoice->setInvoiceTotal();

if($request->has('recurring-invoice-check'))
$eventExists = ($invoice->event) ? true : false;

if ($request->has('recurring-invoice-check'))
{
if($request->input('recurring-invoice-check') === 'on')

if($request->input('recurring-invoice-check') === 'on' && $request->input('recurring-details') === 'standalone')
{
$invoicesCount = $invoice->event->invoices()->count();
$invoice->invoice_event_id = null;
$invoice->save();

//Check if last invoice and delete if so
if($invoicesCount == 1)
{
$invoice->event->delete();
}
}
elseif($request->input('recurring-invoice-check') === 'on')
{
//$repeatsEveryInterval is the number of times the event needs to occur in a time period
//$repeatsEveryTimePeriod is the time period in which an event needs to occur (day, week, month, year)
//$repeatUntilOption is the duration of which the event needs to occur until
//--never option is forever
//--occurence option is how many occurences for it to occur till the event stops
//--date option is until a specific date

$repeatsEveryInterval = $request->input('recurring-time-interval');
$repeatsEveryTimePeriod = $request->input('recurring-time-period');
$repeatUntilOption = $request->input('recurring-until');
$repeatUntilMeta = null;

switch($repeatUntilOption)
{
switch ($repeatUntilOption) {
case 'occurence':
$numberOfOccurences = $request->input('recurring-until-occurence-number');
$repeatUntilMeta = $numberOfOccurences;
Expand All @@ -469,56 +484,68 @@ public function update(UpdateInvoiceRequest $request, Invoice $invoice)
}

$startDate = Carbon::now();
$timezone = new DateTimeZone('Asia/Singapore');
$timezone = new DateTimeZone('UTC');
$rruleString = Unicorn::generateRrule($startDate, $timezone, $repeatsEveryInterval, $repeatsEveryTimePeriod, $repeatUntilOption, $repeatUntilMeta);

$eventExists = ($invoice->event) ? true : false;

$invoiceEvent = ($eventExists) ? $invoice->event : new InvoiceEvent;
$invoiceEvent->time_interval = $repeatsEveryInterval;
$invoiceEvent->time_period = $repeatsEveryTimePeriod;
$invoiceEvent->until_type = $repeatUntilOption;
$invoiceEvent->until_meta = $repeatUntilMeta;
$invoiceEvent->rule = $rruleString;
$invoiceEvent->company_id = $invoice->company_id;
$invoiceEvent->save();

$invoice->invoice_event_id = $invoiceEvent->id;
$invoice->save();

$items = $invoice->items;

if($eventExists)
{
$invoiceTemplate = $invoiceEvent->template;
$invoiceTemplate->fill($invoice->toArray());
$invoiceTemplate->save();

foreach($items as $item)
if ($eventExists) {
if($request->input('recurring-details') === 'future')
{
$invoiceItemTemplate = new InvoiceItemTemplate;
$invoiceItemTemplate->fill($item->toArray());
$invoiceItemTemplate->save();
$invoiceTemplate = $invoiceEvent->template;
$invoiceTemplate->fill($invoice->toArray());
$invoiceTemplate->save();

$invoiceItemTemplates = $invoiceTemplate->items;

foreach($invoiceItemTemplates as $invoiceItemTemplate)
{
$invoiceItemTemplate->delete();
}

foreach ($items as $item)
{
$invoiceItemTemplate = new InvoiceItemTemplate;
$invoiceItemTemplate->fill($item->toArray());
$invoiceItemTemplate->invoice_template_id = $invoiceTemplate->id;
$invoiceItemTemplate->save();
}
}
}
else
{
$invoiceTemplate = new InvoiceTemplate;
$invoiceTemplate->fill($invoice->toArray());
$invoiceTemplate->invoice_event_id = $invoiceEvent->id;
$invoiceTemplate->save();

foreach($items as $item)
} else {
if($request->input('recurring-details') === 'none')
{
$invoiceItemTemplate = new InvoiceItemTemplate;
$invoiceItemTemplate->fill($item->toArray());
$invoiceItemTemplate->invoice_template_id = $invoiceTemplate->id;
$invoiceItemTemplate->save();
$invoiceTemplate = new InvoiceTemplate;
$invoiceTemplate->fill($invoice->toArray());
$invoiceTemplate->invoice_event_id = $invoiceEvent->id;
$invoiceTemplate->save();

foreach ($items as $item) {
$invoiceItemTemplate = new InvoiceItemTemplate;
$invoiceItemTemplate->fill($item->toArray());
$invoiceItemTemplate->invoice_template_id = $invoiceTemplate->id;
$invoiceItemTemplate->save();
}
}
}


}
}
}
else
{
if($eventExists) : $invoice->event->delete(); endif;
}

flash('Invoice Updated', 'success');

Expand Down Expand Up @@ -555,6 +582,19 @@ public function history(Invoice $invoice)
return view('pages.invoice.history', compact('invoice', 'client', 'histories'));
}

/**
* Function to check if the invoice has any siblings
*
* @param Invoice $invoice
* @return \Illuminate\Http\JsonResponse
*/
public function checkSiblings(Invoice $invoice)
{
$hasSiblings = ($invoice->siblings()) ? true : false;

return response()->json(compact('hasSiblings'));
}

/**
* Show the form for creating a new resource.
*
Expand Down
1 change: 1 addition & 0 deletions app/Http/Requests/UpdateInvoiceRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public function rules()
return [
'date' => 'required',
'netdays' => 'required|numeric',
'recurring-details' => 'required|in:none,standalone,future'
];
}
}
6 changes: 6 additions & 0 deletions app/Models/Invoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ public function history()
return $this->hasMany(OldInvoice::class);
}

public function siblings()
{
return $this->event->invoices->except($this->id);
}

public function owns($model)
{
return $this->id == $model->invoice_id;
Expand Down Expand Up @@ -248,6 +253,7 @@ public function duplicate($date = null)
$duedate = $date->addDays($this->netdays)->startOfDay()->toDateTimeString();
$cloned->duedate = $duedate;
$cloned->status = self::STATUS_DRAFT;
$cloned->invoice_event_id = null;
$cloned->save();

foreach($this->items as $item)
Expand Down
2 changes: 2 additions & 0 deletions app/Models/InvoiceTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ class InvoiceTemplate extends Model
* @var array
*/
protected $fillable = [
'date',
'netdays',
'client_id'
];

public function event()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ public function up()
{
Schema::create('invoice_events', function (Blueprint $table) {
$table->increments('id');
$table->integer('time_interval');
$table->string('time_period');
$table->string('until_type');
$table->string('until_meta')->nullable();
$table->string('rule');
$table->integer('invoice_id')->unsigned()->unique();
$table->foreign('invoice_id')
->references('id')->on('invoices')
$table->integer('company_id')->unsigned();
$table->foreign('company_id')
->references('id')->on('companies')
->onDelete('cascade');
$table->timestamps();
$table->softDeletes();
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ public function up()
{
Schema::create('invoice_templates', function (Blueprint $table) {
$table->increments('id');
$table->dateTime('date');
$table->integer('netdays');
$table->integer('client_id')->unsigned();
$table->foreign('client_id')
->references('id')->on('clients')
->onDelete('cascade');
$table->integer('invoice_event_id')->unsigned();
$table->foreign('invoice_event_id')
->references('id')->on('invoice_events')
Expand Down

This file was deleted.

3 changes: 3 additions & 0 deletions resources/assets/sass/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ mark {
}

/* Modifications for Elements */
[type="radio"] + span {
color: #000000;
}
:root:root:root input.radio-input-inline {
display: inline;
border: none;
Expand Down

0 comments on commit f53665c

Please sign in to comment.