mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-05 18:52:44 +01:00
Working on Invitations
This commit is contained in:
parent
e364bcf6ec
commit
86d123ff9a
@ -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'),
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
}
|
@ -42,6 +42,6 @@ class Invoice extends BaseModel
|
||||
|
||||
public function invitations()
|
||||
{
|
||||
$this->morphMany(Invitation::class, 'inviteable');
|
||||
return $this->hasMany(InvoiceInvitation::class);
|
||||
}
|
||||
}
|
||||
|
54
app/Models/InvoiceInvitation.php
Normal file
54
app/Models/InvoiceInvitation.php
Normal 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));
|
||||
}
|
||||
|
||||
}
|
@ -30,6 +30,7 @@ class Quote extends BaseModel
|
||||
|
||||
public function invitations()
|
||||
{
|
||||
$this->morphMany(Invitation::class, 'inviteable');
|
||||
return $this->hasMany(QuoteInvitation::class);
|
||||
}
|
||||
|
||||
}
|
||||
|
54
app/Models/QuoteInvitation.php
Normal file
54
app/Models/QuoteInvitation.php
Normal 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));
|
||||
}
|
||||
|
||||
}
|
@ -33,6 +33,6 @@ class RecurringInvoice extends BaseModel
|
||||
|
||||
public function invitations()
|
||||
{
|
||||
$this->morphMany(Invitation::class, 'inviteable');
|
||||
$this->morphMany(RecurringInvoiceInvitation::class);
|
||||
}
|
||||
}
|
||||
|
54
app/Models/RecurringInvoiceInvitation.php
Normal file
54
app/Models/RecurringInvoiceInvitation.php
Normal 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));
|
||||
}
|
||||
|
||||
}
|
@ -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) {
|
||||
|
@ -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'),
|
||||
|
@ -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']);
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user