mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-05 03:34:36 -04:00
Fixes for settings, implement invitations from invoice request (#3047)
* Fixes for client portal localization * Replace Invoice Ninja Logo with user defined logo and website URL in client portal * Minor Fixes * Refactor for invitations on invoices * Fixes for settings
This commit is contained in:
parent
3405b91c64
commit
a6f928b181
@ -126,13 +126,13 @@ class CompanySettings extends BaseSettings
|
|||||||
public $quote_design_id = '1';
|
public $quote_design_id = '1';
|
||||||
public $invoice_footer = '';
|
public $invoice_footer = '';
|
||||||
public $invoice_labels = '';
|
public $invoice_labels = '';
|
||||||
public $show_item_taxes = false;
|
|
||||||
public $tax_name1 = '';
|
public $tax_name1 = '';
|
||||||
public $tax_rate1 = 0;
|
public $tax_rate1 = 0;
|
||||||
public $tax_name2 = '';
|
public $tax_name2 = '';
|
||||||
public $tax_rate2 = 0;
|
public $tax_rate2 = 0;
|
||||||
public $tax_name3 = '';
|
public $tax_name3 = '';
|
||||||
public $tax_rate3 = 0;
|
public $tax_rate3 = 0;
|
||||||
|
public $number_of_tax_rates = 1;
|
||||||
public $payment_type_id = '1';
|
public $payment_type_id = '1';
|
||||||
public $custom_fields = '';
|
public $custom_fields = '';
|
||||||
public $invoice_fields = '';
|
public $invoice_fields = '';
|
||||||
@ -190,9 +190,9 @@ class CompanySettings extends BaseSettings
|
|||||||
public $schedule_reminder2 = ''; // (enum: after_invoice_date, before_due_date, after_due_date)
|
public $schedule_reminder2 = ''; // (enum: after_invoice_date, before_due_date, after_due_date)
|
||||||
public $schedule_reminder3 = ''; // (enum: after_invoice_date, before_due_date, after_due_date)
|
public $schedule_reminder3 = ''; // (enum: after_invoice_date, before_due_date, after_due_date)
|
||||||
|
|
||||||
public $late_fee_amount1 = '';
|
public $late_fee_amount1 = 0;
|
||||||
public $late_fee_amount2 = '';
|
public $late_fee_amount2 = 0;
|
||||||
public $late_fee_amount3 = '';
|
public $late_fee_amount3 = 0;
|
||||||
|
|
||||||
public $endless_reminder_frequency_id = '0';
|
public $endless_reminder_frequency_id = '0';
|
||||||
|
|
||||||
@ -226,6 +226,7 @@ class CompanySettings extends BaseSettings
|
|||||||
|
|
||||||
|
|
||||||
public static $casts = [
|
public static $casts = [
|
||||||
|
'number_of_tax_rates' => 'int',
|
||||||
'email_subject_custom1' => 'string',
|
'email_subject_custom1' => 'string',
|
||||||
'email_subject_custom2' => 'string',
|
'email_subject_custom2' => 'string',
|
||||||
'email_subject_custom3' => 'string',
|
'email_subject_custom3' => 'string',
|
||||||
@ -241,9 +242,9 @@ class CompanySettings extends BaseSettings
|
|||||||
'schedule_reminder1' => 'string', // (enum: after_invoice_date, before_due_date, after_due_date)
|
'schedule_reminder1' => 'string', // (enum: after_invoice_date, before_due_date, after_due_date)
|
||||||
'schedule_reminder2' => 'string', // (enum: after_invoice_date, before_due_date, after_due_date)
|
'schedule_reminder2' => 'string', // (enum: after_invoice_date, before_due_date, after_due_date)
|
||||||
'schedule_reminder3' => 'string', // (enum: after_invoice_date, before_due_date, after_due_date)
|
'schedule_reminder3' => 'string', // (enum: after_invoice_date, before_due_date, after_due_date)
|
||||||
'late_fee_amount1' => 'string',
|
'late_fee_amount1' => 'float',
|
||||||
'late_fee_amount2' => 'string',
|
'late_fee_amount2' => 'float',
|
||||||
'late_fee_amount3' => 'string',
|
'late_fee_amount3' => 'float',
|
||||||
'endless_reminder_frequency_id' => 'integer',
|
'endless_reminder_frequency_id' => 'integer',
|
||||||
'client_online_payment_notification' => 'bool',
|
'client_online_payment_notification' => 'bool',
|
||||||
'client_manual_payment_notification' => 'bool',
|
'client_manual_payment_notification' => 'bool',
|
||||||
@ -355,7 +356,6 @@ class CompanySettings extends BaseSettings
|
|||||||
'reset_counter_date' => 'string',
|
'reset_counter_date' => 'string',
|
||||||
'require_invoice_signature' => 'bool',
|
'require_invoice_signature' => 'bool',
|
||||||
'require_quote_signature' => 'bool',
|
'require_quote_signature' => 'bool',
|
||||||
'show_item_taxes' => 'bool',
|
|
||||||
'state' => 'string',
|
'state' => 'string',
|
||||||
'email' => 'string',
|
'email' => 'string',
|
||||||
'vat_number' => 'string',
|
'vat_number' => 'string',
|
||||||
|
@ -24,7 +24,7 @@ class InvoiceInvitationFactory
|
|||||||
$ii->user_id = $user_id;
|
$ii->user_id = $user_id;
|
||||||
$ii->client_contact_id = null;
|
$ii->client_contact_id = null;
|
||||||
$ii->invoice_id = null;
|
$ii->invoice_id = null;
|
||||||
$ii->invitation_key = Str::random(config('ninja.key_length'));
|
$ii->key = Str::random(config('ninja.key_length'));
|
||||||
$ii->transaction_reference = null;
|
$ii->transaction_reference = null;
|
||||||
$ii->message_id = null;
|
$ii->message_id = null;
|
||||||
$ii->email_error = '';
|
$ii->email_error = '';
|
||||||
|
@ -113,7 +113,7 @@ class ForgotPasswordController extends Controller
|
|||||||
|
|
||||||
return $response == Password::RESET_LINK_SENT
|
return $response == Password::RESET_LINK_SENT
|
||||||
? response()->json(['message' => 'Reset link sent to your email.', 'status' => true], 201)
|
? response()->json(['message' => 'Reset link sent to your email.', 'status' => true], 201)
|
||||||
: response()->json(['message' => 'Unable to send reset link', 'status' => false], 401);
|
: response()->json(['message' => 'Email not found', 'status' => false], 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,4 +48,10 @@ class InvitationController extends Controller
|
|||||||
abort(404);
|
abort(404);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public function invoiceRouterForIframe(string $client_hash, string $invitation_key)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,10 @@
|
|||||||
* @OA\Property(property="fill_products", type="boolean", example=true, description="Toggles filling a product description based on product key"),
|
* @OA\Property(property="fill_products", type="boolean", example=true, description="Toggles filling a product description based on product key"),
|
||||||
* @OA\Property(property="convert_products", type="boolean", example=true, description="___________"),
|
* @OA\Property(property="convert_products", type="boolean", example=true, description="___________"),
|
||||||
* @OA\Property(property="update_products", type="boolean", example=true, description="Toggles updating a product description which description changes"),
|
* @OA\Property(property="update_products", type="boolean", example=true, description="Toggles updating a product description which description changes"),
|
||||||
* @OA\Property(property="custom_surcharge_taxes", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"),
|
* @OA\Property(property="custom_surcharge_taxes1", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"),
|
||||||
|
* @OA\Property(property="custom_surcharge_taxes2", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"),
|
||||||
|
* @OA\Property(property="custom_surcharge_taxes3", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"),
|
||||||
|
* @OA\Property(property="custom_surcharge_taxes4", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"),
|
||||||
* @OA\Property(property="logo", type="object", example="logo.png", description="The company logo - binary"),
|
* @OA\Property(property="logo", type="object", example="logo.png", description="The company logo - binary"),
|
||||||
* @OA\Property(property="settings",ref="#/components/schemas/CompanySettings"),
|
* @OA\Property(property="settings",ref="#/components/schemas/CompanySettings"),
|
||||||
* )
|
* )
|
||||||
|
@ -159,9 +159,9 @@
|
|||||||
* @OA\Property(property="schedule_reminder1", type="string", example="after_invoice_date", description="(enum: after_invoice_date, before_due_date, after_due_date)"),
|
* @OA\Property(property="schedule_reminder1", type="string", example="after_invoice_date", description="(enum: after_invoice_date, before_due_date, after_due_date)"),
|
||||||
* @OA\Property(property="schedule_reminder2", type="string", example="after_invoice_date", description="(enum: after_invoice_date, before_due_date, after_due_date)"),
|
* @OA\Property(property="schedule_reminder2", type="string", example="after_invoice_date", description="(enum: after_invoice_date, before_due_date, after_due_date)"),
|
||||||
* @OA\Property(property="schedule_reminder3", type="string", example="after_invoice_date", description="(enum: after_invoice_date, before_due_date, after_due_date)"),
|
* @OA\Property(property="schedule_reminder3", type="string", example="after_invoice_date", description="(enum: after_invoice_date, before_due_date, after_due_date)"),
|
||||||
* @OA\Property(property="late_fee_amount1", type="string", example="10.00", description="____________"),
|
* @OA\Property(property="late_fee_amount1", type="float", example=10.00, description="____________"),
|
||||||
* @OA\Property(property="late_fee_amount2", type="string", example="20.00", description="____________"),
|
* @OA\Property(property="late_fee_amount2", type="float", example=20.00, description="____________"),
|
||||||
* @OA\Property(property="late_fee_amount3", type="string", example="100.00", description="____________"),
|
* @OA\Property(property="late_fee_amount3", type="float", example=100.00, description="____________"),
|
||||||
* @OA\Property(property="endless_reminder_frequency_id", type="string", example="1", description="____________"),
|
* @OA\Property(property="endless_reminder_frequency_id", type="string", example="1", description="____________"),
|
||||||
* @OA\Property(property="client_online_payment_notification", type="boolean", example=false, description="____________"),
|
* @OA\Property(property="client_online_payment_notification", type="boolean", example=false, description="____________"),
|
||||||
* @OA\Property(property="client_manual_payment_notification", type="boolean", example=false, description="____________"),
|
* @OA\Property(property="client_manual_payment_notification", type="boolean", example=false, description="____________"),
|
||||||
|
@ -12,11 +12,13 @@
|
|||||||
namespace App\Http\Requests\Invoice;
|
namespace App\Http\Requests\Invoice;
|
||||||
|
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
class UpdateInvoiceRequest extends Request
|
class UpdateInvoiceRequest extends Request
|
||||||
{
|
{
|
||||||
|
use MakesHash;
|
||||||
/**
|
/**
|
||||||
* Determine if the user is authorized to make this request.
|
* Determine if the user is authorized to make this request.
|
||||||
*
|
*
|
||||||
@ -34,7 +36,7 @@ class UpdateInvoiceRequest extends Request
|
|||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
|
|
||||||
//$this->sanitize();
|
$this->sanitize();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'documents' => 'mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx',
|
'documents' => 'mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx',
|
||||||
@ -47,6 +49,9 @@ class UpdateInvoiceRequest extends Request
|
|||||||
{
|
{
|
||||||
$input = $this->all();
|
$input = $this->all();
|
||||||
|
|
||||||
|
if(isset($input['client_id']))
|
||||||
|
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
|
|
||||||
return $this->all();
|
return $this->all();
|
||||||
|
@ -23,6 +23,7 @@ use Illuminate\Contracts\Translation\HasLocalePreference;
|
|||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Laracasts\Presenter\PresentableTrait;
|
use Laracasts\Presenter\PresentableTrait;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ class Gateway extends StaticModel
|
|||||||
'is_offsite' => 'boolean',
|
'is_offsite' => 'boolean',
|
||||||
'is_secure' => 'boolean',
|
'is_secure' => 'boolean',
|
||||||
'recommended' => 'boolean',
|
'recommended' => 'boolean',
|
||||||
'visible' => 'boolean',
|
//'visible' => 'boolean',
|
||||||
'updated_at' => 'timestamp',
|
'updated_at' => 'timestamp',
|
||||||
'created_at' => 'timestamp',
|
'created_at' => 'timestamp',
|
||||||
'default_gateway_type_id' => 'string',
|
'default_gateway_type_id' => 'string',
|
||||||
|
@ -23,6 +23,8 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
|
|
||||||
class GroupSetting extends StaticModel
|
class GroupSetting extends StaticModel
|
||||||
{
|
{
|
||||||
|
use MakesHash;
|
||||||
|
|
||||||
public $timestamps = false;
|
public $timestamps = false;
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
@ -52,5 +54,15 @@ class GroupSetting extends StaticModel
|
|||||||
return $this->hasMany(Client::class, 'id', 'group_settings_id');
|
return $this->hasMany(Client::class, 'id', 'group_settings_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the model for a bound value.
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @return \Illuminate\Database\Eloquent\Model|null
|
||||||
|
*/
|
||||||
|
public function resolveRouteBinding($value)
|
||||||
|
{
|
||||||
|
return $this
|
||||||
|
->where('id', $this->decodePrimaryKey($value))->firstOrFail();
|
||||||
|
}
|
||||||
}
|
}
|
@ -21,8 +21,9 @@ class InvoiceInvitation extends BaseModel
|
|||||||
|
|
||||||
use MakesDates;
|
use MakesDates;
|
||||||
|
|
||||||
protected $guarded = [
|
protected $fillable = [
|
||||||
'id',
|
'id',
|
||||||
|
'client_contact_id',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function entityType()
|
public function entityType()
|
||||||
|
@ -13,6 +13,7 @@ namespace App\Repositories;
|
|||||||
|
|
||||||
use App\Models\Activity;
|
use App\Models\Activity;
|
||||||
use App\Models\Backup;
|
use App\Models\Backup;
|
||||||
|
use App\Models\Client;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,6 +55,17 @@ class ActivityRepository extends BaseRepository
|
|||||||
{
|
{
|
||||||
$backup = new Backup();
|
$backup = new Backup();
|
||||||
|
|
||||||
|
// if(get_class($entity) == Client::class)
|
||||||
|
// $settings = $entity->getMergedSettings();
|
||||||
|
// else
|
||||||
|
// $settings = $entity->client->getMergedSettings();
|
||||||
|
// $entity->clientMergedDettings = $settings;
|
||||||
|
|
||||||
|
if(get_class($entity) == Client::class)
|
||||||
|
$entity->load('company');
|
||||||
|
else
|
||||||
|
$entity->load('company','client');
|
||||||
|
|
||||||
$backup->activity_id = $activity->id;
|
$backup->activity_id = $activity->id;
|
||||||
$backup->json_backup = $entity->toJson();
|
$backup->json_backup = $entity->toJson();
|
||||||
$backup->save();
|
$backup->save();
|
||||||
|
@ -34,7 +34,7 @@ class ClientContactRepository extends BaseRepository
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Set first record to primary - always*/
|
/* Set first record to primary - always */
|
||||||
$contacts = $contacts->sortBy('is_primary');
|
$contacts = $contacts->sortBy('is_primary');
|
||||||
|
|
||||||
$contacts->first(function($contact){
|
$contacts->first(function($contact){
|
||||||
|
@ -72,7 +72,39 @@ class InvoiceRepository extends BaseRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event(new CreateInvoiceInvitation($invoice));
|
|
||||||
|
if(isset($data['invitations']))
|
||||||
|
{
|
||||||
|
|
||||||
|
$invitations = collect($data['invitations']);
|
||||||
|
|
||||||
|
/* Get array of Keyss which have been removed from the invitations array and soft delete each invitation */
|
||||||
|
collect($invoice->invitations->pluck('key'))->diff($invitations->pluck('key'))->each(function($invitation){
|
||||||
|
|
||||||
|
InvoiceInvitation::destroy($invitation);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
foreach($data['invitations'] as $invitation)
|
||||||
|
{
|
||||||
|
$inv = InvoiceInvitation::whereKey($invitation['key'])->first();
|
||||||
|
|
||||||
|
if(!$inv)
|
||||||
|
{
|
||||||
|
$invitation['client_contact_id'] = $this->decodePrimaryKey($invitation['client_contact_id']);
|
||||||
|
|
||||||
|
$new_invitation = InvoiceInvitationFactory::create($invoice->company_id, $invoice->user_id);
|
||||||
|
$new_invitation->fill($invitation);
|
||||||
|
$new_invitation->invoice_id = $invoice->id;
|
||||||
|
$new_invitation->save();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//event(new CreateInvoiceInvitation($invoice));
|
||||||
|
|
||||||
$invoice = $invoice->calc()->getInvoice();
|
$invoice = $invoice->calc()->getInvoice();
|
||||||
|
|
||||||
@ -88,7 +120,7 @@ class InvoiceRepository extends BaseRepository
|
|||||||
if($finished_amount != $starting_amount)
|
if($finished_amount != $starting_amount)
|
||||||
UpdateCompanyLedgerWithInvoice::dispatchNow($invoice, ($finished_amount - $starting_amount));
|
UpdateCompanyLedgerWithInvoice::dispatchNow($invoice, ($finished_amount - $starting_amount));
|
||||||
|
|
||||||
return $invoice;
|
return $invoice->fresh();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,8 @@ class ClientTransformer extends EntityTransformer
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->encodePrimaryKey($client->id),
|
'id' => $this->encodePrimaryKey($client->id),
|
||||||
|
'user_id' => $this->encodePrimaryKey($client->user_id),
|
||||||
|
'assigned_user_id' => $this->encodePrimaryKey($client->assigned_user_id),
|
||||||
'name' => $client->name ?: '',
|
'name' => $client->name ?: '',
|
||||||
'website' => $client->website ?: '',
|
'website' => $client->website ?: '',
|
||||||
'private_notes' => $client->private_notes ?: '',
|
'private_notes' => $client->private_notes ?: '',
|
||||||
@ -89,7 +91,7 @@ class ClientTransformer extends EntityTransformer
|
|||||||
'shipping_state' => $client->shipping_state ?: '',
|
'shipping_state' => $client->shipping_state ?: '',
|
||||||
'shipping_postal_code' => $client->shipping_postal_code ?: '',
|
'shipping_postal_code' => $client->shipping_postal_code ?: '',
|
||||||
'shipping_country_id' => $client->shipping_country_id ?: '',
|
'shipping_country_id' => $client->shipping_country_id ?: '',
|
||||||
'settings' => $client->settings ?: '',
|
'settings' => $client->settings ?: new \stdClass,
|
||||||
'is_deleted' => (bool) $client->is_deleted,
|
'is_deleted' => (bool) $client->is_deleted,
|
||||||
'vat_number' => $client->vat_number ?: '',
|
'vat_number' => $client->vat_number ?: '',
|
||||||
'id_number' => $client->id_number ?: '',
|
'id_number' => $client->id_number ?: '',
|
||||||
|
@ -18,10 +18,12 @@ use App\Models\Company;
|
|||||||
use App\Models\CompanyGateway;
|
use App\Models\CompanyGateway;
|
||||||
use App\Models\CompanyUser;
|
use App\Models\CompanyUser;
|
||||||
use App\Models\GroupSetting;
|
use App\Models\GroupSetting;
|
||||||
|
use App\Models\TaxRate;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Transformers\CompanyGatewayTransformer;
|
use App\Transformers\CompanyGatewayTransformer;
|
||||||
use App\Transformers\CompanyUserTransformer;
|
use App\Transformers\CompanyUserTransformer;
|
||||||
use App\Transformers\GroupSettingTransformer;
|
use App\Transformers\GroupSettingTransformer;
|
||||||
|
use App\Transformers\TaxRateTransformer;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,7 +74,11 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'update_products' => (bool)$company->update_products,
|
'update_products' => (bool)$company->update_products,
|
||||||
'fill_products' => (bool)$company->fill_products,
|
'fill_products' => (bool)$company->fill_products,
|
||||||
'convert_products' => (bool)$company->convert_products,
|
'convert_products' => (bool)$company->convert_products,
|
||||||
'custom_surcharge_taxes' => (bool)$company->custom_surcharge_taxes,
|
'custom_surcharge_taxes1' => (bool)$company->custom_surcharge_taxes1,
|
||||||
|
'custom_surcharge_taxes2' => (bool)$company->custom_surcharge_taxes2,
|
||||||
|
'custom_surcharge_taxes3' => (bool)$company->custom_surcharge_taxes3,
|
||||||
|
'custom_surcharge_taxes4' => (bool)$company->custom_surcharge_taxes4,
|
||||||
|
'custom_fields' => (string) $company->custom_fields,
|
||||||
'size_id' => (string) $company->size_id ?: '',
|
'size_id' => (string) $company->size_id ?: '',
|
||||||
'industry_id' => (string) $company->industry_id ?: '',
|
'industry_id' => (string) $company->industry_id ?: '',
|
||||||
'first_month_of_year' => (string) $company->first_month_of_year ?: '',
|
'first_month_of_year' => (string) $company->first_month_of_year ?: '',
|
||||||
@ -133,4 +139,13 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
return $this->includeItem($company->account, $transformer, Account::class);
|
return $this->includeItem($company->account, $transformer, Account::class);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function includeTaxRates(Company $company)
|
||||||
|
{
|
||||||
|
|
||||||
|
$transformer = new TaxRateTransformer($this->serializer);
|
||||||
|
|
||||||
|
return $this->includeCollection($company->tax_rates, $transformer, TaxRate::class);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ class GatewayTransformer extends EntityTransformer
|
|||||||
'provider' => (string)$gateway->provider ?: '',
|
'provider' => (string)$gateway->provider ?: '',
|
||||||
'visible' => (bool)$gateway->visible,
|
'visible' => (bool)$gateway->visible,
|
||||||
'sort_order' => (int)$gateway->sort_order,
|
'sort_order' => (int)$gateway->sort_order,
|
||||||
'recommended' => (bool)$gateway->recommended,
|
//'recommended' => (bool)$gateway->recommended,
|
||||||
'site_url' => (string)$gateway->site_url ?: '',
|
'site_url' => (string)$gateway->site_url ?: '',
|
||||||
'is_offsite' => (bool)$gateway->is_offsite,
|
'is_offsite' => (bool)$gateway->is_offsite,
|
||||||
'is_secure' => (bool)$gateway->is_secure,
|
'is_secure' => (bool)$gateway->is_secure,
|
||||||
|
@ -24,7 +24,8 @@ class InvoiceInvitationTransformer extends EntityTransformer
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => $this->encodePrimaryKey($invitation->id),
|
'id' => $this->encodePrimaryKey($invitation->id),
|
||||||
'key' => $invitation->getName() ?: '',
|
'client_contact_id' => $this->encodePrimaryKey($invitation->client_contact_id),
|
||||||
|
'key' => $invitation->key,
|
||||||
'link' => $invitation->getLink() ?: '',
|
'link' => $invitation->getLink() ?: '',
|
||||||
'sent_date' => $invitation->sent_date ?: '',
|
'sent_date' => $invitation->sent_date ?: '',
|
||||||
'viewed_date' => $invitation->sent_date ?: '',
|
'viewed_date' => $invitation->sent_date ?: '',
|
||||||
|
@ -83,6 +83,8 @@ class InvoiceTransformer extends EntityTransformer
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->encodePrimaryKey($invoice->id),
|
'id' => $this->encodePrimaryKey($invoice->id),
|
||||||
|
'user_id' => $this->encodePrimaryKey($invoice->user_id),
|
||||||
|
'assigned_user_id' => $this->encodePrimaryKey($invoice->assigned_user_id),
|
||||||
'amount' => (float) $invoice->amount,
|
'amount' => (float) $invoice->amount,
|
||||||
'balance' => (float) $invoice->balance,
|
'balance' => (float) $invoice->balance,
|
||||||
'client_id' => (string) $this->encodePrimaryKey($invoice->client_id),
|
'client_id' => (string) $this->encodePrimaryKey($invoice->client_id),
|
||||||
|
@ -55,6 +55,8 @@ class PaymentTransformer extends EntityTransformer
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->encodePrimaryKey($payment->id),
|
'id' => $this->encodePrimaryKey($payment->id),
|
||||||
|
'user_id' => $this->encodePrimaryKey($payment->user_id),
|
||||||
|
'assigned_user_id' => $this->encodePrimaryKey($payment->assigned_user_id),
|
||||||
'amount' => (float) $payment->amount,
|
'amount' => (float) $payment->amount,
|
||||||
'transaction_reference' => $payment->transaction_reference ?: '',
|
'transaction_reference' => $payment->transaction_reference ?: '',
|
||||||
'payment_date' => $payment->payment_date ?: '',
|
'payment_date' => $payment->payment_date ?: '',
|
||||||
|
@ -60,6 +60,8 @@ class ProductTransformer extends EntityTransformer
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->encodePrimaryKey($product->id),
|
'id' => $this->encodePrimaryKey($product->id),
|
||||||
|
'user_id' => $this->encodePrimaryKey($product->user_id),
|
||||||
|
'assigned_user_id' => $this->encodePrimaryKey($product->assigned_user_id),
|
||||||
'product_key' => $product->product_key ?: '',
|
'product_key' => $product->product_key ?: '',
|
||||||
'notes' => $product->notes ?: '',
|
'notes' => $product->notes ?: '',
|
||||||
'cost' => (float) $product->cost ?: 0,
|
'cost' => (float) $product->cost ?: 0,
|
||||||
|
@ -80,6 +80,8 @@ class QuoteTransformer extends EntityTransformer
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->encodePrimaryKey($quote->id),
|
'id' => $this->encodePrimaryKey($quote->id),
|
||||||
|
'user_id' => $this->encodePrimaryKey($quote->user_id),
|
||||||
|
'assigned_user_id' => $this->encodePrimaryKey($quote->assigned_user_id),
|
||||||
'amount' => (float) $quote->amount ?: '',
|
'amount' => (float) $quote->amount ?: '',
|
||||||
'balance' => (float) $quote->balance ?: '',
|
'balance' => (float) $quote->balance ?: '',
|
||||||
'client_id' => (string) $quote->client_id,
|
'client_id' => (string) $quote->client_id,
|
||||||
|
@ -81,6 +81,8 @@ class RecurringInvoiceTransformer extends EntityTransformer
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->encodePrimaryKey($invoice->id),
|
'id' => $this->encodePrimaryKey($invoice->id),
|
||||||
|
'user_id' => $this->encodePrimaryKey($invoice->user_id),
|
||||||
|
'assigned_user_id' => $this->encodePrimaryKey($invoice->assigned_user_id),
|
||||||
'amount' => (float) $invoice->amount ?: '',
|
'amount' => (float) $invoice->amount ?: '',
|
||||||
'balance' => (float) $invoice->balance ?: '',
|
'balance' => (float) $invoice->balance ?: '',
|
||||||
'client_id' => (string) $invoice->client_id,
|
'client_id' => (string) $invoice->client_id,
|
||||||
|
@ -81,6 +81,8 @@ class RecurringQuoteTransformer extends EntityTransformer
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->encodePrimaryKey($quote->id),
|
'id' => $this->encodePrimaryKey($quote->id),
|
||||||
|
'user_id' => $this->encodePrimaryKey($quote->user_id),
|
||||||
|
'assigned_user_id' => $this->encodePrimaryKey($quote->assigned_user_id),
|
||||||
'amount' => (float) $quote->amount ?: '',
|
'amount' => (float) $quote->amount ?: '',
|
||||||
'balance' => (float) $quote->balance ?: '',
|
'balance' => (float) $quote->balance ?: '',
|
||||||
'client_id' => (string) $quote->client_id,
|
'client_id' => (string) $quote->client_id,
|
||||||
|
@ -83,7 +83,7 @@ class CreateUsersTable extends Migration
|
|||||||
$table->string('provider');
|
$table->string('provider');
|
||||||
$table->boolean('visible')->default(true);
|
$table->boolean('visible')->default(true);
|
||||||
$table->unsignedInteger('sort_order')->default(10000);
|
$table->unsignedInteger('sort_order')->default(10000);
|
||||||
$table->boolean('recommended')->default(0);
|
//$table->boolean('recommended')->default(0);
|
||||||
$table->string('site_url', 200)->nullable();
|
$table->string('site_url', 200)->nullable();
|
||||||
$table->boolean('is_offsite')->default(false);
|
$table->boolean('is_offsite')->default(false);
|
||||||
$table->boolean('is_secure')->default(false);
|
$table->boolean('is_secure')->default(false);
|
||||||
@ -668,7 +668,7 @@ class CreateUsersTable extends Migration
|
|||||||
$t->unsignedInteger('user_id');
|
$t->unsignedInteger('user_id');
|
||||||
$t->unsignedInteger('client_contact_id');
|
$t->unsignedInteger('client_contact_id');
|
||||||
$t->unsignedInteger('invoice_id')->index();
|
$t->unsignedInteger('invoice_id')->index();
|
||||||
$t->string('invitation_key')->index()->unique();
|
$t->string('key')->index();
|
||||||
$t->timestamps(6);
|
$t->timestamps(6);
|
||||||
$t->softDeletes();
|
$t->softDeletes();
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ class PaymentLibrariesSeeder extends Seeder
|
|||||||
['name' => 'GoCardless', 'provider' => 'GoCardlessV2\Redirect', 'sort_order' => 9, 'is_offsite' => true, 'key' => 'b9886f9257f0c6ee7c302f1c74475f6c', 'fields' => '{"accessToken":"","webhookSecret":"","testMode":true}'],
|
['name' => 'GoCardless', 'provider' => 'GoCardlessV2\Redirect', 'sort_order' => 9, 'is_offsite' => true, 'key' => 'b9886f9257f0c6ee7c302f1c74475f6c', 'fields' => '{"accessToken":"","webhookSecret":"","testMode":true}'],
|
||||||
['name' => 'PagSeguro', 'provider' => 'PagSeguro', 'key' => 'ef498756b54db63c143af0ec433da803', 'fields' => '{"email":"","token":"","sandbox":false}'],
|
['name' => 'PagSeguro', 'provider' => 'PagSeguro', 'key' => 'ef498756b54db63c143af0ec433da803', 'fields' => '{"email":"","token":"","sandbox":false}'],
|
||||||
['name' => 'PAYMILL', 'provider' => 'Paymill', 'key' => 'ca52f618a39367a4c944098ebf977e1c', 'fields' => '{"apiKey":""}'],
|
['name' => 'PAYMILL', 'provider' => 'Paymill', 'key' => 'ca52f618a39367a4c944098ebf977e1c', 'fields' => '{"apiKey":""}'],
|
||||||
['name' => 'Custom', 'provider' => 'Custom2', 'is_offsite' => true, 'sort_order' => 21, 'key' => '54faab2ab6e3223dbe848b1686490baa', 'fields' => ''],
|
['name' => 'Custom', 'provider' => 'Custom2', 'is_offsite' => true, 'sort_order' => 21, 'key' => '54faab2ab6e3223dbe848b1686490baa', 'fields' => '{"text":"","name":""}'],
|
||||||
['name' => 'Custom', 'provider' => 'Custom3', 'is_offsite' => true, 'sort_order' => 22, 'key' => '8149a02d9e691a78da2664d0ce9ce1a9', 'fields' => ''],
|
['name' => 'Custom', 'provider' => 'Custom3', 'is_offsite' => true, 'sort_order' => 22, 'key' => '8149a02d9e691a78da2664d0ce9ce1a9', 'fields' => ''],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ class RandomDataSeeder extends Seeder
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
factory(\App\Models\Client::class, 6)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){
|
factory(\App\Models\Client::class, 10)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){
|
||||||
|
|
||||||
factory(\App\Models\ClientContact::class,1)->create([
|
factory(\App\Models\ClientContact::class,1)->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<form method="POST" action="{{ route($passwordEmailRoute) }}">
|
<form method="POST" action="{{ route($passwordEmailRoute) }}">
|
||||||
@csrf
|
@csrf
|
||||||
<h1>trans('texts.password_recovery')</h1>
|
<h1>{{trans('texts.password_recovery')}}</h1>
|
||||||
<p class="text-muted"></p>
|
<p class="text-muted"></p>
|
||||||
<div class="input-group mb-3">
|
<div class="input-group mb-3">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
@ -23,7 +23,7 @@
|
|||||||
<i class="icon-user"></i>
|
<i class="icon-user"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" placeholder="trans('texts.email')" required autofocus>
|
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" placeholder="{{trans('texts.email')}}" required autofocus>
|
||||||
|
|
||||||
@if ($errors->has('email'))
|
@if ($errors->has('email'))
|
||||||
<span class="invalid-feedback" role="alert">
|
<span class="invalid-feedback" role="alert">
|
||||||
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<button class="btn btn-primary px-4" type="submit">trans('texts.send_email')</button>
|
<button class="btn btn-primary px-4" type="submit">{{trans('texts.send_email')}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<form method="POST" action="{{ route('client.password.update') }}">
|
<form method="POST" action="{{ route('client.password.update') }}">
|
||||||
@csrf
|
@csrf
|
||||||
<input type="hidden" name="token" value="{{ $token }}">
|
<input type="hidden" name="token" value="{{ $token }}">
|
||||||
<h1>@lang('texts.change_password')</h1>
|
<h1>{{trans('texts.change_password')}}</h1>
|
||||||
<p class="text-muted"></p>
|
<p class="text-muted"></p>
|
||||||
<div class="input-group mb-3">
|
<div class="input-group mb-3">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<i class="icon-user"></i>
|
<i class="icon-user"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" placeholder="@lang('texts.email')" required autofocus>
|
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" placeholder="{{trans('texts.email')}}" required autofocus>
|
||||||
|
|
||||||
@if ($errors->has('email'))
|
@if ($errors->has('email'))
|
||||||
<span class="invalid-feedback" role="alert">
|
<span class="invalid-feedback" role="alert">
|
||||||
@ -36,7 +36,7 @@
|
|||||||
<i class="icon-lock"></i>
|
<i class="icon-lock"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" placeholder="@lang('texts.password')" required>
|
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" placeholder="{{trans('texts.password')}}" required>
|
||||||
|
|
||||||
@if ($errors->has('password'))
|
@if ($errors->has('password'))
|
||||||
<span class="invalid-feedback" role="alert">
|
<span class="invalid-feedback" role="alert">
|
||||||
@ -51,12 +51,12 @@
|
|||||||
<i class="icon-lock"></i>
|
<i class="icon-lock"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" placeholder="@lang('texts.confirm_password')" required>
|
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" placeholder="{{trans('texts.confirm_password')}}" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<button class="btn btn-primary px-4" type="submit">@lang('texts.change_password')</button>
|
<button class="btn btn-primary px-4" type="submit">{{trans('texts.change_password')}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
<button class="navbar-toggler sidebar-toggler d-lg-none mr-auto" type="button" data-toggle="sidebar-show">
|
<button class="navbar-toggler sidebar-toggler d-lg-none mr-auto" type="button" data-toggle="sidebar-show">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
<a class="navbar-brand" href="https://invoiceninja.com">
|
<a class="navbar-brand" href="{!! $settings->website ?: 'https://invoiceninja.com' !!}">
|
||||||
<img class="navbar-brand-full" src="/images/logo.png" width="50" height="50" alt="Invoice Ninja Logo">
|
<img class="navbar-brand-full" src="{!! $settings->company_logo ?: '/images/logo.png' !!}" width="50" height="50" alt="Invoice Ninja Logo">
|
||||||
<img class="navbar-brand-minimized" src="/images/logo.png" width="30" height="30" alt="Invoice Ninja Logo">
|
<img class="navbar-brand-minimized" src="{!! $settings->company_logo ?: '/images/logo.png' !!}" width="30" height="30" alt="Invoice Ninja Logo">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<button class="navbar-toggler sidebar-toggler sidebar-minimizer" type="button" data-toggle="sidebar-show">
|
<button class="navbar-toggler sidebar-toggler sidebar-minimizer" type="button" data-toggle="sidebar-show">
|
||||||
|
@ -62,7 +62,7 @@ $(function() {
|
|||||||
drawCallback: function(settings){
|
drawCallback: function(settings){
|
||||||
|
|
||||||
data = this.api().ajax.json().data;
|
data = this.api().ajax.json().data;
|
||||||
console.log(data);
|
|
||||||
},
|
},
|
||||||
columns: [
|
columns: [
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ Route::group(['middleware' => ['domain_db'], 'prefix' => 'client', 'as' => 'clie
|
|||||||
|
|
||||||
/*Invitation catches*/
|
/*Invitation catches*/
|
||||||
Route::get('invoice/{invitation_id}','ClientPortal\InvitationController@invoiceRouter');
|
Route::get('invoice/{invitation_id}','ClientPortal\InvitationController@invoiceRouter');
|
||||||
|
//Route::get('invoice/{client_hash}/{invitation_id}','ClientPortal\InvitationController@invoiceRouterForIframe'); we shouldn't need this if we force subdomain for the clients
|
||||||
Route::get('payment_hook/{company_gateway_id}/{gateway_type_id}','ClientPortal\PaymentHookController@process');
|
Route::get('payment_hook/{company_gateway_id}/{gateway_type_id}','ClientPortal\PaymentHookController@process');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -55,7 +55,7 @@ class CompanySettingsTest extends TestCase
|
|||||||
$casts = CompanySettings::$casts;
|
$casts = CompanySettings::$casts;
|
||||||
|
|
||||||
$diff = array_diff_key($company_settings, $casts);
|
$diff = array_diff_key($company_settings, $casts);
|
||||||
\Log::error($diff);
|
|
||||||
$this->assertEquals(1, count($diff));
|
$this->assertEquals(1, count($diff));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user