Skip to content

Commit

Permalink
Merge branch 'feature/recurring_invoices_pregenerated'
Browse files Browse the repository at this point in the history
  • Loading branch information
zanechua committed Nov 9, 2018
2 parents 8616f6e + c6c49bd commit 087c3df
Show file tree
Hide file tree
Showing 51 changed files with 2,163 additions and 46 deletions.
135 changes: 135 additions & 0 deletions app/Console/Commands/GenerateRecurringInvoices.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php

namespace App\Console\Commands;

use App\Models\Invoice;
use App\Models\InvoiceEvent;
use App\Models\InvoiceItem;
use Carbon\Carbon;
use DateTimeZone;
use Illuminate\Console\Command;
use App\Library\Poowf\Unicorn;
use Illuminate\Support\Facades\Log;
use Recurr\Rule;
use Recurr\Transformer\ArrayTransformer;
use Recurr\Transformer\Constraint\AfterConstraint;
use Recurr\Transformer\Constraint\BeforeConstraint;

class GenerateRecurringInvoices extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'invoice:generate';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate recurring invoices';

/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}

/**
* Execute the console command.
*
* @return mixed
* @throws \Recurr\Exception\InvalidRRule
* @throws \Recurr\Exception\InvalidWeekday
*/
public function handle()
{
$invoiceEvents = InvoiceEvent::all();

$timezone = new DateTimeZone('Asia/Singapore');

foreach($invoiceEvents as $event)
{
$company = $event->company;
$now = Carbon::now();

switch($event->time_period)
{
case 'day':
$constraintTime = $now->addDay($event->time_interval + 2);
break;
case 'week':
$constraintTime = $now->addWeek(($event->time_interval + 2));
break;
case 'month':
$constraintTime = $now->addMonth($event->time_interval + 2);
break;
case 'year':
$constraintTime = $now->addYear($event->time_interval + 2);
break;
}

$constraint = new BeforeConstraint($constraintTime);

// $rrule = Unicorn::generateRrule($event->created_at, $timezone, $event->time_interval, $event->time_period, $event->until_type, $event->until_meta, true);
$rrule = Rule::createFromString($event->rule);
$transformer = new ArrayTransformer();

$recurrences = $transformer->transform($rrule, $constraint);

foreach($recurrences as $key => $recurrence)
{
if($key == 2)
{
break;
}

$template = $event->template;
$templateItems = $template->items;
$generatedInvoice = new Invoice;
$generatedInvoice->fill($template->toArray());
$duedate = Carbon::createFromFormat('Y-m-d H:i:s', $recurrence->getEnd()->format('Y-m-d H:i:s'))->addDays($generatedInvoice->netdays)->toDateTimeString();
$generatedInvoice->date = Carbon::createFromFormat('Y-m-d H:i:s', $recurrence->getEnd()->format('Y-m-d H:i:s'))->toDateTimeString();
$generatedInvoice->duedate = $duedate;
$generatedInvoice->client_id = $template->client_id;
$generatedInvoice->company_id = $company->id;
$generatedInvoice->invoice_event_id = $event->id;
$generatedInvoice->status = Invoice::STATUS_DRAFT;
$generatedInvoice->notify = $template->notify;

//Generate hash based on the serialized version of the invoice;
$hash = hash('sha512', serialize($generatedInvoice . $templateItems));

if(Invoice::where('hash', $hash)->count() == 1)
{
print_r("Invoice already generated\n");
}
else
{
$generatedInvoice->nice_invoice_id = $company->niceinvoiceid();
$generatedInvoice->hash = $hash;
$generatedInvoice->save();

foreach($templateItems as $key => $item)
{
$invoiceitem = new InvoiceItem;
$invoiceitem->name = $item;
$invoiceitem->description = $item->description;
$invoiceitem->quantity = $item->quantity;
$invoiceitem->price = $item->price;
$invoiceitem->invoice_id = $generatedInvoice->id;
$invoiceitem->save();
}

$generatedInvoice->setInvoiceTotal();
}
}
}
}
}
66 changes: 66 additions & 0 deletions app/Console/Commands/ProcessNotifiableInvoices.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace App\Console\Commands;

use App\Models\Invoice;
use App\Models\InvoiceEvent;
use App\Notifications\InvoiceNotification;
use Carbon\Carbon;
use DateTimeZone;
use Illuminate\Console\Command;
use App\Library\Poowf\Unicorn;
use Illuminate\Support\Facades\Log;
use Recurr\Rule;
use Recurr\Transformer\ArrayTransformer;
use Recurr\Transformer\Constraint\AfterConstraint;
use Recurr\Transformer\Constraint\BeforeConstraint;

class ProcessNotifiableInvoices extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'invoice:notify';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Process the generated recurring invoices';

/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}

/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$startDate = Carbon::now()->subDay();
$endDate = Carbon::now()->addDay();
$invoices = Invoice::datebetween($startDate, $endDate)->notifiable()->get();
foreach($invoices as $invoice)
{
$company = $invoice->company;
$localDate = Carbon::now($company->timezone);
$localInvoiceDate = Carbon::createFromFormat('Y-m-d H:i:s', $invoice->date, $company->timezone);

if(date_diff($localDate, $localInvoiceDate)->format('%a') === '0')
{
$invoice->notify(new InvoiceNotification($invoice));
}
}
}
}
4 changes: 2 additions & 2 deletions app/Console/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ class Kernel extends ConsoleKernel
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
$schedule->command('invoice:process')
->twiceDaily(07, 19);
}

/**
Expand Down
5 changes: 3 additions & 2 deletions app/Http/Controllers/ClientController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Http\Requests\CreateClientRequest;
use App\Http\Requests\UpdateClientRequest;
use App\Models\Client;
use PragmaRX\Countries\Package\Countries;
use Storage;
use Uuid;
use Image;
Expand All @@ -31,7 +32,7 @@ public function index()
*/
public function create()
{
$countries = countries();
$countries = (new Countries())->all();

return view('pages.client.create', compact('countries'));
}
Expand Down Expand Up @@ -99,7 +100,7 @@ public function show(Client $client)
*/
public function edit(Client $client)
{
$countries = countries();
$countries = (new Countries())->all();

return view('pages.client.edit', compact('client', 'countries'));
}
Expand Down
111 changes: 109 additions & 2 deletions app/Http/Controllers/CompanyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use App\Http\Requests\UpdateCompanyUserRequest;
use App\Notifications\NewCompanyUserNotification;
use Illuminate\Http\Request;
use PragmaRX\Countries\Package\Countries;
use App\Models\Company;
use App\Models\User;
use Storage;
Expand All @@ -34,7 +35,10 @@ public function index()
*/
public function create()
{
return view('pages.company.create');
$countries = (new Countries())->all();
$timezones = \DateTimeZone::listIdentifiers(\DateTimeZone::ALL);

return view('pages.company.create', compact('countries', 'timezones'));
}

/**
Expand All @@ -49,8 +53,20 @@ public function store(CreateCompanyRequest $request)
$company = new Company;
$company->fill($request->all());
$company->user_id = $request->session()->pull('user_id');
if($request->has('country_code'))
{
$timezone = (new Countries())
->where('iso_3166_1_alpha2', $request->input('country_code'))
->first()
->hydrate('timezones')
->timezones
->first()
->zone_name;
dd($timezone);
}
$company->save();


$storedirectory = '/perm_store/company/' . $company->id . '/photos/';

Storage::makeDirectory($storedirectory);
Expand Down Expand Up @@ -130,7 +146,10 @@ public function show()
public function edit()
{
$company = auth()->user()->ownedcompany;
return view('pages.company.edit', compact('company'));
$countries = (new Countries())->all();
$timezones = \DateTimeZone::listIdentifiers(\DateTimeZone::ALL);

return view('pages.company.edit', compact('company', 'countries', 'timezones'));
}

/**
Expand Down Expand Up @@ -253,6 +272,94 @@ public function update_owner(UpdateCompanyOwnerRequest $request) {
return redirect()->back();
}

public function index_users() {
$company = auth()->user()->company;

if($company)
{
$users = $company->users()->paginate(12);
}
else
{
$users = collect();
}

return view('pages.company.users.index', compact('users', 'company'));
}

public function create_users() {
$company = auth()->user()->company;
$countries = (new Countries())->all();
$timezones = \DateTimeZone::listIdentifiers(\DateTimeZone::ALL);

return view('pages.company.users.create', compact('company', 'countries', 'timezones'));
}
public function store_users(CreateCompanyUserRequest $request) {
$company = auth()->user()->company;

$random_password = str_random(16);

$user = new User;
$user->fill($request->all());
$user->password = $random_password;
$user->company_id = $company->id;
$user->save();

$user->notify(new NewCompanyUserNotification($user, $random_password));

return redirect()->back();
}

public function edit_users(User $user) {
$countries = (new Countries())->all();
$timezones = \DateTimeZone::listIdentifiers(\DateTimeZone::ALL);
return view('pages.company.users.edit', compact('user', 'countries', 'timezones'));
}

public function update_users(UpdateCompanyUserRequest $request, User $user) {
$user->fill($request->all());
if ($request->has('newpassword') && $request->input('newpassword') != null) {
$newpass = $request->input('newpassword');
$user->password = $newpass;
}
$user->save();

return redirect()->back();
}

public function destroy_users(Request $request, User $user) {

$auth_user = auth()->user();
$usercompany = $user->company;

//TODO: Probably need to rewrite/refactor this logic to somewhere else
if ($usercompany)
{
if ($usercompany->isOwner($auth_user))
{
if($user->id != $auth_user->id)
{
$user->delete();
flash('User Deleted', 'success');
}
else
{
flash('You cannot delete the owner of the Company', 'error');
}
}
else
{
flash('Unauthorised', 'error');
}
}
else
{
flash('Nothing was done', 'error');
}

return redirect()->back();
}

public function show_check()
{
return view('pages.company.check');
Expand Down

0 comments on commit 087c3df

Please sign in to comment.