mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge pull request #4173 from turbo124/v5-develop
Validation rules for projects / clients.
This commit is contained in:
commit
2e233a6437
@ -154,10 +154,12 @@ class CompanySettings extends BaseSettings
|
|||||||
public $email_style_custom = ''; //the template itself
|
public $email_style_custom = ''; //the template itself
|
||||||
public $email_subject_invoice = '';
|
public $email_subject_invoice = '';
|
||||||
public $email_subject_quote = '';
|
public $email_subject_quote = '';
|
||||||
|
public $email_subject_credit = '';
|
||||||
public $email_subject_payment = '';
|
public $email_subject_payment = '';
|
||||||
public $email_subject_payment_partial = '';
|
public $email_subject_payment_partial = '';
|
||||||
public $email_subject_statement = '';
|
public $email_subject_statement = '';
|
||||||
public $email_template_invoice = '';
|
public $email_template_invoice = '';
|
||||||
|
public $email_template_credit = '';
|
||||||
public $email_template_quote = '';
|
public $email_template_quote = '';
|
||||||
public $email_template_payment = '';
|
public $email_template_payment = '';
|
||||||
public $email_template_payment_partial = '';
|
public $email_template_payment_partial = '';
|
||||||
@ -350,10 +352,12 @@ class CompanySettings extends BaseSettings
|
|||||||
'email_signature' => 'string',
|
'email_signature' => 'string',
|
||||||
'email_subject_invoice' => 'string',
|
'email_subject_invoice' => 'string',
|
||||||
'email_subject_quote' => 'string',
|
'email_subject_quote' => 'string',
|
||||||
|
'email_subject_credit' => 'string',
|
||||||
'email_subject_payment' => 'string',
|
'email_subject_payment' => 'string',
|
||||||
'email_subject_payment_partial' => 'string',
|
'email_subject_payment_partial' => 'string',
|
||||||
'email_template_invoice' => 'string',
|
'email_template_invoice' => 'string',
|
||||||
'email_template_quote' => 'string',
|
'email_template_quote' => 'string',
|
||||||
|
'email_template_credit' => 'string',
|
||||||
'email_template_payment' => 'string',
|
'email_template_payment' => 'string',
|
||||||
'email_template_payment_partial' => 'string',
|
'email_template_payment_partial' => 'string',
|
||||||
'email_subject_reminder1' => 'string',
|
'email_subject_reminder1' => 'string',
|
||||||
|
@ -30,6 +30,9 @@ class EmailTemplateDefaults
|
|||||||
case 'email_template_quote':
|
case 'email_template_quote':
|
||||||
return self::emailQuoteTemplate();
|
return self::emailQuoteTemplate();
|
||||||
break;
|
break;
|
||||||
|
case 'email_template_credit':
|
||||||
|
return self::emailCreditTemplate();
|
||||||
|
break;
|
||||||
case 'email_template_payment':
|
case 'email_template_payment':
|
||||||
return self::emailPaymentTemplate();
|
return self::emailPaymentTemplate();
|
||||||
break;
|
break;
|
||||||
@ -69,6 +72,9 @@ class EmailTemplateDefaults
|
|||||||
case 'email_subject_quote':
|
case 'email_subject_quote':
|
||||||
return self::emailQuoteSubject();
|
return self::emailQuoteSubject();
|
||||||
break;
|
break;
|
||||||
|
case 'email_subject_credit':
|
||||||
|
return self::emailCreditSubject();
|
||||||
|
break;
|
||||||
case 'email_subject_payment':
|
case 'email_subject_payment':
|
||||||
return self::emailPaymentSubject();
|
return self::emailPaymentSubject();
|
||||||
break;
|
break;
|
||||||
@ -109,7 +115,11 @@ class EmailTemplateDefaults
|
|||||||
public static function emailInvoiceSubject()
|
public static function emailInvoiceSubject()
|
||||||
{
|
{
|
||||||
return ctrans('texts.invoice_subject', ['number'=>'$number', 'account'=>'$company.name']);
|
return ctrans('texts.invoice_subject', ['number'=>'$number', 'account'=>'$company.name']);
|
||||||
//return Parsedown::instance()->line(self::transformText('invoice_subject'));
|
}
|
||||||
|
|
||||||
|
public static function emailCreditSubject()
|
||||||
|
{
|
||||||
|
return ctrans('texts.credit_subject', ['number'=>'$number', 'account'=>'$company.name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function emailInvoiceTemplate()
|
public static function emailInvoiceTemplate()
|
||||||
@ -122,14 +132,11 @@ class EmailTemplateDefaults
|
|||||||
$invoice_message = '<p>'.self::transformText('invoice_message').'</p><br><br><p>$view_link</p>';
|
$invoice_message = '<p>'.self::transformText('invoice_message').'</p><br><br><p>$view_link</p>';
|
||||||
|
|
||||||
return $invoice_message;
|
return $invoice_message;
|
||||||
//return $converter->convertToHtml($invoice_message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function emailQuoteSubject()
|
public static function emailQuoteSubject()
|
||||||
{
|
{
|
||||||
return ctrans('texts.quote_subject', ['number'=>'$number', 'account'=>'$company.name']);
|
return ctrans('texts.quote_subject', ['number'=>'$number', 'account'=>'$company.name']);
|
||||||
|
|
||||||
//return Parsedown::instance()->line(self::transformText('quote_subject'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function emailQuoteTemplate()
|
public static function emailQuoteTemplate()
|
||||||
@ -158,6 +165,17 @@ class EmailTemplateDefaults
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function emailCreditTemplate()
|
||||||
|
{
|
||||||
|
$converter = new CommonMarkConverter([
|
||||||
|
'html_input' => 'strip',
|
||||||
|
'allow_unsafe_links' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $converter->convertToHtml(self::transformText('credit_message'));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static function emailPaymentPartialTemplate()
|
public static function emailPaymentPartialTemplate()
|
||||||
{
|
{
|
||||||
$converter = new CommonMarkConverter([
|
$converter = new CommonMarkConverter([
|
||||||
|
@ -17,6 +17,7 @@ use App\Events\Misc\InvitationWasViewed;
|
|||||||
use App\Events\Quote\QuoteWasViewed;
|
use App\Events\Quote\QuoteWasViewed;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\InvoiceInvitation;
|
use App\Models\InvoiceInvitation;
|
||||||
|
use App\Models\RecurringInvoiceInvitation;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\Traits\MakesDates;
|
use App\Utils\Traits\MakesDates;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
@ -13,6 +13,7 @@ namespace App\Http\Requests\Invoice;
|
|||||||
|
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
use App\Http\ValidationRules\Invoice\UniqueInvoiceNumberRule;
|
use App\Http\ValidationRules\Invoice\UniqueInvoiceNumberRule;
|
||||||
|
use App\Http\ValidationRules\Project\ValidProjectForClient;
|
||||||
use App\Models\ClientContact;
|
use App\Models\ClientContact;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Utils\Traits\CleanLineItems;
|
use App\Utils\Traits\CleanLineItems;
|
||||||
@ -47,12 +48,14 @@ class StoreInvoiceRequest extends Request
|
|||||||
$rules['documents'] = 'file|mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:20000';
|
$rules['documents'] = 'file|mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:20000';
|
||||||
}
|
}
|
||||||
|
|
||||||
$rules['client_id'] = 'required|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
$rules['client_id'] = 'bail|required|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
||||||
|
|
||||||
$rules['invitations.*.client_contact_id'] = 'distinct';
|
$rules['invitations.*.client_contact_id'] = 'distinct';
|
||||||
|
|
||||||
$rules['number'] = new UniqueInvoiceNumberRule($this->all());
|
$rules['number'] = new UniqueInvoiceNumberRule($this->all());
|
||||||
|
|
||||||
|
$rules['project_id'] = ['bail', 'sometimes', new ValidProjectForClient($this->all())];
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +71,10 @@ class StoreInvoiceRequest extends Request
|
|||||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('project_id', $input) && is_string($input['project_id'])) {
|
||||||
|
$input['project_id'] = $this->decodePrimaryKey($input['project_id']);
|
||||||
|
}
|
||||||
|
|
||||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,8 @@ class StoreProjectRequest extends Request
|
|||||||
{
|
{
|
||||||
$rules = [];
|
$rules = [];
|
||||||
|
|
||||||
$rules['name'] ='required|unique:projects,name,null,null,company_id,'.auth()->user()->companyId();
|
//$rules['name'] ='required|unique:projects,name,null,null,company_id,'.auth()->user()->companyId();
|
||||||
|
$rules['name'] = 'required';
|
||||||
$rules['client_id'] = 'required|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
$rules['client_id'] = 'required|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace App\Http\Requests\RecurringInvoice;
|
namespace App\Http\Requests\RecurringInvoice;
|
||||||
|
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
|
use App\Http\ValidationRules\Recurring\UniqueRecurringInvoiceNumberRule;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\RecurringInvoice;
|
use App\Models\RecurringInvoice;
|
||||||
use App\Utils\Traits\CleanLineItems;
|
use App\Utils\Traits\CleanLineItems;
|
||||||
@ -52,6 +53,8 @@ class StoreRecurringInvoiceRequest extends Request
|
|||||||
|
|
||||||
$rules['frequency_id'] = 'required|integer';
|
$rules['frequency_id'] = 'required|integer';
|
||||||
|
|
||||||
|
$rules['number'] = new UniqueRecurringInvoiceNumberRule($this->all());
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,10 @@ class UpdateRecurringInvoiceRequest extends Request
|
|||||||
$rules['documents'] = 'file|mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:20000';
|
$rules['documents'] = 'file|mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:20000';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->input('number')) {
|
||||||
|
$rules['number'] = 'unique:recurring_invoices,number,'.$this->id.',id,company_id,'.$this->recurring_invoice->company_id;
|
||||||
|
}
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,10 +48,13 @@ class StoreVendorRequest extends Request
|
|||||||
|
|
||||||
protected function prepareForValidation()
|
protected function prepareForValidation()
|
||||||
{
|
{
|
||||||
// $input = $this->all();
|
$input = $this->all();
|
||||||
|
|
||||||
|
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||||
// $this->replace($input);
|
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->replace($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function messages()
|
public function messages()
|
||||||
|
@ -69,6 +69,10 @@ class UpdateVendorRequest extends Request
|
|||||||
{
|
{
|
||||||
$input = $this->all();
|
$input = $this->all();
|
||||||
|
|
||||||
|
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||||
|
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||||
|
}
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
55
app/Http/ValidationRules/Project/ValidProjectForClient.php
Normal file
55
app/Http/ValidationRules/Project/ValidProjectForClient.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\ValidationRules\Project;
|
||||||
|
|
||||||
|
use App\Models\Project;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Illuminate\Contracts\Validation\Rule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ValidProjectForClient.
|
||||||
|
*/
|
||||||
|
class ValidProjectForClient implements Rule
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
|
||||||
|
public $input;
|
||||||
|
|
||||||
|
public function __construct($input)
|
||||||
|
{
|
||||||
|
$this->input = $input;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param string $attribute
|
||||||
|
* @param mixed $value
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function passes($attribute, $value)
|
||||||
|
{
|
||||||
|
if(is_string($this->input['project_id']))
|
||||||
|
$this->input['project_id'] = $this->decodePrimaryKey($this->input['project_id']);
|
||||||
|
|
||||||
|
$project = Project::findOrFail($this->input['project_id']);
|
||||||
|
|
||||||
|
return $project->client_id == $this->input['client_id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function message()
|
||||||
|
{
|
||||||
|
return "Project client does not match entity client";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\ValidationRules\Recurring;
|
||||||
|
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Models\RecurringInvoice;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Contracts\Validation\Rule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class UniqueRecurringInvoiceNumberRule.
|
||||||
|
*/
|
||||||
|
class UniqueRecurringInvoiceNumberRule implements Rule
|
||||||
|
{
|
||||||
|
public $input;
|
||||||
|
|
||||||
|
public function __construct($input)
|
||||||
|
{
|
||||||
|
$this->input = $input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $attribute
|
||||||
|
* @param mixed $value
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function passes($attribute, $value)
|
||||||
|
{
|
||||||
|
return $this->checkIfInvoiceNumberUnique(); //if it exists, return false!
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function message()
|
||||||
|
{
|
||||||
|
return "Recurring Invoice number {$this->input['number']} already taken";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $email
|
||||||
|
*
|
||||||
|
* //off,when_sent,when_paid
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function checkIfInvoiceNumberUnique() : bool
|
||||||
|
{
|
||||||
|
if(empty($this->input['number']))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
$invoice = RecurringInvoice::where('client_id', $this->input['client_id'])
|
||||||
|
->where('number', $this->input['number'])
|
||||||
|
->withTrashed()
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($invoice) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -50,7 +50,7 @@ class RecurringInvoiceInvitation extends BaseModel
|
|||||||
*/
|
*/
|
||||||
public function contact()
|
public function contact()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(ClientContact::class)->withTrashed();
|
return $this->belongsTo(ClientContact::class, 'client_contact_id', 'id')->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,6 +57,7 @@ class VendorRepository extends BaseRepository
|
|||||||
*/
|
*/
|
||||||
public function save(array $data, Vendor $vendor) : ?Vendor
|
public function save(array $data, Vendor $vendor) : ?Vendor
|
||||||
{
|
{
|
||||||
|
|
||||||
$vendor->fill($data);
|
$vendor->fill($data);
|
||||||
|
|
||||||
$vendor->save();
|
$vendor->save();
|
||||||
|
@ -28,7 +28,7 @@ class CompanyLedgerTransformer extends EntityTransformer
|
|||||||
*/
|
*/
|
||||||
public function transform(CompanyLedger $company_ledger)
|
public function transform(CompanyLedger $company_ledger)
|
||||||
{
|
{
|
||||||
$entity_name = lcfirst(class_basename($company_ledger->company_ledgerable_type)).'_id';
|
$entity_name = lcfirst(rtrim(class_basename($company_ledger->company_ledgerable_type), 's')).'_id';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
$entity_name => (string) $this->encodePrimaryKey($company_ledger->company_ledgerable_id),
|
$entity_name => (string) $this->encodePrimaryKey($company_ledger->company_ledgerable_id),
|
||||||
|
@ -104,6 +104,10 @@ trait AppSetup
|
|||||||
'subject' => EmailTemplateDefaults::emailStatementSubject(),
|
'subject' => EmailTemplateDefaults::emailStatementSubject(),
|
||||||
'body' => EmailTemplateDefaults::emailStatementTemplate(),
|
'body' => EmailTemplateDefaults::emailStatementTemplate(),
|
||||||
],
|
],
|
||||||
|
'credit' => [
|
||||||
|
'subject' => EmailTemplateDefaults::emailCreditSubject(),
|
||||||
|
'body' => EmailTemplateDefaults::emailCreditTemplate(),
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
Cache::forever($name, $data);
|
Cache::forever($name, $data);
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace App\Utils\Traits;
|
namespace App\Utils\Traits;
|
||||||
|
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Inviteable.
|
* Class Inviteable.
|
||||||
*/
|
*/
|
||||||
@ -42,7 +44,9 @@ trait Inviteable
|
|||||||
|
|
||||||
public function getLink() :string
|
public function getLink() :string
|
||||||
{
|
{
|
||||||
$entity_type = strtolower(class_basename($this->entityType()));
|
//$entity_type = strtolower(class_basename($this->entityType()));
|
||||||
|
|
||||||
|
$entity_type = Str::snake(class_basename($this->entityType()));
|
||||||
|
|
||||||
//$this->with('company','contact',$this->entity_type);
|
//$this->with('company','contact',$this->entity_type);
|
||||||
//$this->with('company');
|
//$this->with('company');
|
||||||
|
@ -3283,5 +3283,7 @@ return [
|
|||||||
'saved_at' => 'Saved at :time',
|
'saved_at' => 'Saved at :time',
|
||||||
'credit_payment' => 'Credit applied to Invoice :invoice_number',
|
'credit_payment' => 'Credit applied to Invoice :invoice_number',
|
||||||
|
|
||||||
|
'credit_subject' => 'New credit :number from :account',
|
||||||
|
'credit_message' => 'To view your credit for :amount, click the link below.',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -31,7 +31,7 @@ Route::group(['middleware' => ['auth:contact', 'locale'], 'prefix' => 'client',
|
|||||||
Route::get('invoices/{invoice_invitation}', 'ClientPortal\InvoiceController@show')->name('invoice.show_invitation');
|
Route::get('invoices/{invoice_invitation}', 'ClientPortal\InvoiceController@show')->name('invoice.show_invitation');
|
||||||
|
|
||||||
Route::get('recurring_invoices', 'ClientPortal\RecurringInvoiceController@index')->name('recurring_invoices.index')->middleware('portal_enabled');
|
Route::get('recurring_invoices', 'ClientPortal\RecurringInvoiceController@index')->name('recurring_invoices.index')->middleware('portal_enabled');
|
||||||
Route::get('recurring_invoices/{recurring_invoice}', 'ClientPortal\RecurringInvoiceController@show')->name('recurring_invoices.show');
|
Route::get('recurring_invoices/{recurring_invoice}', 'ClientPortal\RecurringInvoiceController@show')->name('recurring_invoice.show');
|
||||||
Route::get('recurring_invoices/{recurring_invoice}/request_cancellation', 'ClientPortal\RecurringInvoiceController@requestCancellation')->name('recurring_invoices.request_cancellation');
|
Route::get('recurring_invoices/{recurring_invoice}/request_cancellation', 'ClientPortal\RecurringInvoiceController@requestCancellation')->name('recurring_invoices.request_cancellation');
|
||||||
|
|
||||||
Route::post('payments/process', 'ClientPortal\PaymentController@process')->name('payments.process');
|
Route::post('payments/process', 'ClientPortal\PaymentController@process')->name('payments.process');
|
||||||
|
@ -99,6 +99,8 @@ class ShopInvoiceTest extends TestCase
|
|||||||
$this->company->enable_shop_api = true;
|
$this->company->enable_shop_api = true;
|
||||||
$this->company->save();
|
$this->company->save();
|
||||||
|
|
||||||
|
Product::truncate();
|
||||||
|
|
||||||
$product = Product::factory()->create([
|
$product = Product::factory()->create([
|
||||||
'user_id' => $this->user->id,
|
'user_id' => $this->user->id,
|
||||||
'company_id' => $this->company->id,
|
'company_id' => $this->company->id,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user