1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 05:02:36 +01:00

Working on Invitations

This commit is contained in:
David Bomba 2019-04-24 10:22:02 +10:00
parent e364bcf6ec
commit 86d123ff9a
14 changed files with 244 additions and 43 deletions

View File

@ -93,9 +93,9 @@ class CompanySettings extends BaseSettings
$config = json_decode(config('ninja.settings'));
return (object) [
'timezone_id' => config('ninja.i18n.timezone'),
'language_id' => config('ninja.i18n.language'),
'currency_id' => config('ninja.i18n.currency'),
'timezone_id' => config('ninja.i18n.timezone_id'),
'language_id' => config('ninja.i18n.language_id'),
'currency_id' => config('ninja.i18n.currency_id'),
'payment_terms' => config('ninja.i18n.payment_terms'),
'datetime_format_id' => config('ninja.i18n.datetime_format'),
'military_time' => config('ninja.i18n.military_time'),

View File

@ -6,6 +6,7 @@ use App\DataMapper\ClientSettings;
use App\Models\Company;
use App\Models\Country;
use App\Models\Filterable;
use App\Models\Timezone;
use App\Utils\Traits\MakesHash;
use Hashids\Hashids;
use Illuminate\Database\Eloquent\SoftDeletes;
@ -43,8 +44,6 @@ class Client extends BaseModel
'settings' => 'object'
];
//protected $dates = ['deleted_at'];
public function getClientSettingsObjectAttribute()
{
return new ClientSettings($this->settings);
@ -80,4 +79,16 @@ class Client extends BaseModel
return $this->belongsTo(Country::class, 'shipping_country_id', 'id');
}
public function timezone()
{
return Timezone::find($this->getSettings()->timezone_id);
}
public function getSettings()
{
return ClientSettings::buildClientSettings($this->company->settings, $this->settings);
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Invitation extends BaseModel
{
public function invoices()
{
return $this->morphedByMany(Invoice::class, 'inviteable');
}
public function proposals()
{
return $this->morphedByMany(Proposal::class, 'inviteable');
}
}

View File

@ -42,6 +42,6 @@ class Invoice extends BaseModel
public function invitations()
{
$this->morphMany(Invitation::class, 'inviteable');
return $this->hasMany(InvoiceInvitation::class);
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace App\Models;
use App\Utils\Traits\MakesDates;
use Illuminate\Database\Eloquent\Model;
class InvoiceInvitation extends BaseModel
{
use MakesDates;
/**
* @return mixed
*/
public function invoice()
{
return $this->belongsTo(Invoice::class)->withTrashed();
}
/**
* @return mixed
*/
public function contact()
{
return $this->belongsTo(ClientContact::class)->withTrashed();
}
/**
* @return mixed
*/
public function user()
{
return $this->belongsTo(User::class)->withTrashed();
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function company()
{
return $this->belongsTo(Company::class);
}
public function signatureDiv()
{
if (! $this->signature_base64) {
return false;
}
return sprintf('<img src="data:image/svg+xml;base64,%s"></img><p/>%s: %s', $this->signature_base64, ctrans('texts.signed'), $this->createClientDate($this->signature_date, $this->contact->client->timezone()->name));
}
}

View File

@ -30,6 +30,7 @@ class Quote extends BaseModel
public function invitations()
{
$this->morphMany(Invitation::class, 'inviteable');
return $this->hasMany(QuoteInvitation::class);
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace App\Models;
use App\Utils\Traits\MakesDates;
use Illuminate\Database\Eloquent\Model;
class QuoteInvitation extends BaseModel
{
use MakesDates;
/**
* @return mixed
*/
public function quote()
{
return $this->belongsTo(Quote::class)->withTrashed();
}
/**
* @return mixed
*/
public function contact()
{
return $this->belongsTo(ClientContact::class)->withTrashed();
}
/**
* @return mixed
*/
public function user()
{
return $this->belongsTo(User::class)->withTrashed();
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function company()
{
return $this->belongsTo(Company::class);
}
public function signatureDiv()
{
if (! $this->signature_base64) {
return false;
}
return sprintf('<img src="data:image/svg+xml;base64,%s"></img><p/>%s: %s', $this->signature_base64, ctrans('texts.signed'), $this->createClientDate($this->signature_date, $this->contact->client->timezone()->name));
}
}

View File

@ -33,6 +33,6 @@ class RecurringInvoice extends BaseModel
public function invitations()
{
$this->morphMany(Invitation::class, 'inviteable');
$this->morphMany(RecurringInvoiceInvitation::class);
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace App\Models;
use App\Utils\Traits\MakesDates;
use Illuminate\Database\Eloquent\Model;
class RecurringInvoiceInvitation extends BaseModel
{
use MakesDates;
/**
* @return mixed
*/
public function recurring_invoice()
{
return $this->belongsTo(RecurringInvoice::class)->withTrashed();
}
/**
* @return mixed
*/
public function contact()
{
return $this->belongsTo(ClientContact::class)->withTrashed();
}
/**
* @return mixed
*/
public function user()
{
return $this->belongsTo(User::class)->withTrashed();
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function company()
{
return $this->belongsTo(Company::class);
}
public function signatureDiv()
{
if (! $this->signature_base64) {
return false;
}
return sprintf('<img src="data:image/svg+xml;base64,%s"></img><p/>%s: %s', $this->signature_base64, ctrans('texts.signed'), $this->createClientDate($this->signature_date, $this->contact->client->timezone()->name));
}
}

View File

@ -2,6 +2,9 @@
namespace App\Providers;
use App\Models\InvoiceInvitation;
use App\Models\QuoteInvitation;
use App\Models\RecurringInvoiceInvitation;
use App\Utils\Traits\MakesHash;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
@ -63,8 +66,16 @@ class RouteServiceProvider extends ServiceProvider
return \App\Models\Expense::withTrashed()->where('id', $this->decodePrimaryKey($value))->firstOrFail();
});
Route::bind('invitation', function ($value) {
return \App\Models\Invitation::withTrashed()->where('id', $this->decodePrimaryKey($value))->firstOrFail();
Route::bind('invoice_invitation', function ($value) {
return \App\Models\InvoiceInvitation::withTrashed()->where('id', $this->decodePrimaryKey($value))->firstOrFail();
});
Route::bind('recurring_invoice_invitation', function ($value) {
return \App\Models\RecurringInvoiceInvitation::withTrashed()->where('id', $this->decodePrimaryKey($value))->firstOrFail();
});
Route::bind('quote_invitation', function ($value) {
return \App\Models\QuoteInvitation::withTrashed()->where('id', $this->decodePrimaryKey($value))->firstOrFail();
});
Route::bind('task', function ($value) {

View File

@ -33,10 +33,10 @@ return [
],
'i18n' => [
'timezone' => env('DEFAULT_TIMEZONE', 15),
'country' => env('DEFAULT_COUNTRY', 840), // United Stated
'currency' => env('DEFAULT_CURRENCY', 1), //USD
'language' => env('DEFAULT_LANGUAGE', 1), //en
'timezone_id' => env('DEFAULT_TIMEZONE', 15),
'country_id' => env('DEFAULT_COUNTRY', 840), // United Stated
'currency_id' => env('DEFAULT_CURRENCY', 1), //USD
'language_id' => env('DEFAULT_LANGUAGE', 1), //en
'date_format' => env('DEFAULT_DATE_FORMAT', 'M j, Y'),
'date_picker_format' => env('DEFAULT_DATE_PICKER_FORMAT', 'M d, yyyy'),
'datetime_format' => env('DEFAULT_DATETIME_FORMAT', 'F j, Y g:i a'),

View File

@ -506,26 +506,33 @@ class CreateUsersTable extends Migration
$t->unique(['company_id', 'quote_number']);
});
Schema::create('invitations', function ($t) {
Schema::create('invoice_invitations', function ($t) {
$t->increments('id');
$t->unsignedInteger('company_id');
$t->unsignedInteger('inviteable_id');
$t->string('inviteable_type');
$t->unsignedInteger('user_id');
$t->unsignedInteger('client_contact_id');
$t->unsignedInteger('invoice_id')->index();
$t->string('invitation_key',100)->index()->unique();
$t->string('invitation_key')->index()->unique();
$t->timestamps();
$t->softDeletes();
$t->string('transaction_reference')->nullable();
$t->string('message_id')->nullable();
$t->text('email_error');
$t->text('signature_base64');
$t->timestamp('signature_date')->nullable();
$t->timestamp('sent_date')->nullable();
$t->timestamp('viewed_date')->nullable();
$t->timestamp('opened_date')->nullable();
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$t->foreign('client_contact_id')->references('id')->on('client_contacts')->onDelete('cascade');
$t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
$t->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
$t->index(['deleted_at', 'invoice_id']);
});

View File

@ -3,6 +3,7 @@
namespace Tests\Feature;
use App\Models\Account;
use App\Models\Client;
use App\Models\Company;
use App\Models\User;
use App\Utils\Traits\MakesHash;
@ -179,4 +180,34 @@ class ClientTest extends TestCase
}
public function testDefaultTimeZoneFromClientModel()
{
$user = User::all()->first();
$company = Company::all()->first();
factory(\App\Models\Client::class, 3)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){
factory(\App\Models\ClientContact::class,1)->create([
'user_id' => $user->id,
'client_id' => $c->id,
'company_id' => $company->id,
'is_primary' => 1
]);
factory(\App\Models\ClientContact::class,2)->create([
'user_id' => $user->id,
'client_id' => $c->id,
'company_id' => $company->id
]);
});
$client = Client::all()->first();
$this->assertEquals($client->getSettings()->timezone_id, 15);
$this->assertEquals($client->timezone()->name, 'US/Eastern');
}
}

View File

@ -20,9 +20,9 @@ use Tests\TestCase;
class LoginTest extends TestCase
{
//use DatabaseTransactions;
use UserSessionAttributes;
use RefreshDatabase;
use DatabaseTransactions;
//use UserSessionAttributes;
//use RefreshDatabase;
public function setUp()
{