1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 13:12:50 +01:00

Merge pull request #7240 from turbo124/v5-develop

Fixes for actions
This commit is contained in:
David Bomba 2022-02-27 18:37:02 +11:00 committed by GitHub
commit 3f82212d9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 99 additions and 47 deletions

View File

@ -46,7 +46,8 @@ class BaseSettings
return is_null($value) ? '' : (string) $value;
case 'bool':
case 'boolean':
return (bool) ($value);
nlog($value);
return boolval($value);
case 'object':
return json_decode($value);
case 'array':

View File

@ -264,15 +264,18 @@ class InvitationController extends Controller
abort(404, "Invoice not found");
}
public function unsubscribe(Request $request, string $invitation_key)
public function unsubscribe(Request $request, string $entity_type, string $invitation_key)
{
if($invite = InvoiceInvitation::withTrashed()->where('key', $invitation_key)->first()){
if($entity_type == 'invoice'){
$invite = InvoiceInvitation::withTrashed()->where('key', $invitation_key)->first();
$invite->contact->send_email = false;
$invite->contact->save();
}elseif($invite = QuoteInvitation::withTrashed()->where('key', $invitation_key)->first()){
}elseif($entity_type == 'quote'){
$invite = QuoteInvitation::withTrashed()->where('key', $invitation_key)->first();
$invite->contact->send_email = false;
$invite->contact->save();
}elseif($invite = CreditInvitation::withTrashed()->where('key', $invitation_key)->first()){
}elseif($entity_type == 'credit'){
$invite = CreditInvitation::withTrashed()->where('key', $invitation_key)->first();
$invite->contact->send_email = false;
$invite->contact->save();
}

View File

@ -37,14 +37,13 @@ class CheckClientExistence
->where('email', auth()->guard('contact')->user()->email)
->whereNotNull('email')
->where('email', '<>', '')
->distinct('company_id')
->distinct('email')
->distinct('client_id')
->whereNotNull('company_id')
->whereHas('client', function ($query) {
return $query->where('is_deleted', false);
})
->whereHas('company', function ($query){
return $query->where('id', auth()->guard('contact')->user()->client->company_id);
return $query->where('companies.account_id', auth()->guard('contact')->user()->company->account_id);
})
->get();

View File

@ -58,7 +58,9 @@ class StoreCreditRequest extends Request
// $rules['number'] = new UniqueCreditNumberRule($this->all());
$rules['number'] = ['nullable', Rule::unique('credits')->where('company_id', auth()->user()->company()->id)];
$rules['discount'] = 'sometimes|numeric';
$rules['is_amount_discount'] = ['boolean'];
if($this->invoice_id)
$rules['invoice_id'] = new ValidInvoiceCreditRule();

View File

@ -58,7 +58,8 @@ class UpdateCreditRequest extends Request
$rules['line_items'] = 'array';
$rules['discount'] = 'sometimes|numeric';
$rules['is_amount_discount'] = ['boolean'];
return $rules;
}

View File

@ -27,7 +27,7 @@ class ActionInvoiceRequest extends Request
*/
private $error_msg;
private $invoice;
// private $invoice;
public function authorize() : bool
{
@ -45,7 +45,9 @@ class ActionInvoiceRequest extends Request
{
$input = $this->all();
if (!array_key_exists('action', $input)) {
if($this->action){
$input['action'] = $this->action;
} elseif (!array_key_exists('action', $input) ) {
$this->error_msg = 'Action is a required field';
} elseif (!$this->invoiceDeletable($this->invoice)) {
unset($input['action']);

View File

@ -55,7 +55,8 @@ class StoreInvoiceRequest extends Request
$rules['number'] = ['nullable', Rule::unique('invoices')->where('company_id', auth()->user()->company()->id)];
$rules['project_id'] = ['bail', 'sometimes', new ValidProjectForClient($this->all())];
$rules['is_amount_discount'] = ['boolean'];
$rules['line_items'] = 'array';
$rules['discount'] = 'sometimes|numeric';

View File

@ -55,6 +55,8 @@ class UpdateInvoiceRequest extends Request
if($this->number)
$rules['number'] = Rule::unique('invoices')->where('company_id', auth()->user()->company()->id)->ignore($this->invoice->id);
$rules['is_amount_discount'] = ['boolean'];
$rules['line_items'] = 'array';
$rules['discount'] = 'sometimes|numeric';

View File

@ -52,6 +52,8 @@ class StoreQuoteRequest extends Request
$rules['number'] = ['nullable',Rule::unique('quotes')->where('company_id', auth()->user()->company()->id)];
$rules['discount'] = 'sometimes|numeric';
$rules['is_amount_discount'] = ['boolean'];
// $rules['number'] = new UniqueQuoteNumberRule($this->all());
$rules['line_items'] = 'array';

View File

@ -52,6 +52,8 @@ class UpdateQuoteRequest extends Request
$rules['line_items'] = 'array';
$rules['discount'] = 'sometimes|numeric';
$rules['is_amount_discount'] = ['boolean'];
return $rules;
}

View File

@ -82,6 +82,9 @@ class PaymentFailureMailer implements ShouldQueue
//determine if this user has the right permissions
$methods = $this->findCompanyUserNotificationType($company_user, ['payment_failure_all','payment_failure', 'payment_failure_user', 'all_notifications']);
if(!is_string($this->error))
$this->error = "Undefined error. Please contact the administrator for further information.";
//if mail is a method type -fire mail!!
if (($key = array_search('mail', $methods)) !== false) {
unset($methods[$key]);

View File

@ -111,7 +111,7 @@ class TemplateEmail extends Mailable
'company' => $company,
'whitelabel' => $this->client->user->account->isPaid() ? true : false,
'logo' => $this->company->present()->logo($settings),
'unsubscribe_link' => $this->invitation->getUnsubscribeLink(),
'unsubscribe_link' => $this->invitation ? $this->invitation->getUnsubscribeLink() : '',
])
->withSwiftMessage(function ($message) use($company){
$message->getHeaders()->addTextHeader('Tag', $company->company_key);

View File

@ -90,6 +90,8 @@ class Credit extends BaseModel
'updated_at' => 'timestamp',
'created_at' => 'timestamp',
'deleted_at' => 'timestamp',
'is_amount_discount' => 'bool',
];
protected $touches = [];

View File

@ -103,6 +103,7 @@ class Invoice extends BaseModel
'created_at' => 'timestamp',
'deleted_at' => 'timestamp',
'is_deleted' => 'bool',
'is_amount_discount' => 'bool',
];
protected $with = [];

View File

@ -89,6 +89,7 @@ class Quote extends BaseModel
'created_at' => 'timestamp',
'deleted_at' => 'timestamp',
'is_deleted' => 'boolean',
'is_amount_discount' => 'bool',
];
protected $dates = [];

View File

@ -141,6 +141,6 @@ class FPX
$this->stripe->client->company,
);
throw new PaymentFailed('Failed to process the payment.', 500);
throw new PaymentFailed('Failed to process the payment.', 400);
}
}

View File

@ -62,7 +62,9 @@ trait Inviteable
else
$domain = config('ninja.app_url');
return $domain.'/client/unsubscribe/'.$this->key;
$entity_type = Str::snake(class_basename($this->entityType()));
return $domain.'/client/unsubscribe/'.$entity_type.'/'.$this->key;
}

2
public/css/app.css vendored

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
/*! For license information please see stripe-fpx.js.LICENSE.txt */
(()=>{var e,t,n,r;function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}new function e(t,n){var r=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),o(this,"setupStripe",(function(){r.stripeConnect?r.stripe=Stripe(r.key,{stripeAccount:r.stripeConnect}):r.stripe=Stripe(r.key);var e=r.stripe.elements();return r.fpx=e.create("fpxBank",{style:{base:{padding:"10px 12px",color:"#32325d",fontSize:"16px"}},accountHolderType:"individual"}),r.fpx.mount("#fpx-bank-element"),r})),o(this,"handle",(function(){document.getElementById("pay-now").addEventListener("click",(function(e){document.getElementById("pay-now").disabled=!0,document.querySelector("#pay-now > svg").classList.remove("hidden"),document.querySelector("#pay-now > span").classList.add("hidden"),r.stripe.confirmFpxPayment(document.querySelector("meta[name=pi-client-secret").content,{payment_method:{fpx:r.fpx},return_url:document.querySelector('meta[name="return-url"]').content})}))})),this.key=t,this.errors=document.getElementById("errors"),this.stripeConnect=n}(null!==(e=null===(t=document.querySelector('meta[name="stripe-publishable-key"]'))||void 0===t?void 0:t.content)&&void 0!==e?e:"",null!==(n=null===(r=document.querySelector('meta[name="stripe-account-id"]'))||void 0===r?void 0:r.content)&&void 0!==n?n:"").setupStripe().handle()})();
(()=>{var e,t,n,r;function o(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var a=function(){function e(t,n){var r=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),i(this,"setupStripe",(function(){r.stripeConnect?r.stripe=Stripe(r.key,{stripeAccount:r.stripeConnect}):r.stripe=Stripe(r.key);var e=r.stripe.elements();return r.fpx=e.create("fpxBank",{style:{base:{padding:"10px 12px",color:"#32325d",fontSize:"16px"}},accountHolderType:"individual"}),r.fpx.mount("#fpx-bank-element"),r})),i(this,"handle",(function(){document.getElementById("pay-now").addEventListener("click",(function(e){document.getElementById("pay-now").disabled=!0,document.querySelector("#pay-now > svg").classList.remove("hidden"),document.querySelector("#pay-now > span").classList.add("hidden"),r.stripe.confirmFpxPayment(document.querySelector("meta[name=pi-client-secret").content,{payment_method:{fpx:r.fpx},return_url:document.querySelector('meta[name="return-url"]').content}).then((function(e){e.error&&r.handleFailure(e.error.message)}))}))})),this.key=t,this.errors=document.getElementById("errors"),this.stripeConnect=n}var t,n,r;return t=e,(n=[{key:"handleFailure",value:function(e){var t=document.getElementById("errors");t.textContent="",t.textContent=e,t.hidden=!1,document.getElementById("pay-now").disabled=!1,document.querySelector("#pay-now > svg").classList.add("hidden"),document.querySelector("#pay-now > span").classList.remove("hidden")}}])&&o(t.prototype,n),r&&o(t,r),e}();new a(null!==(e=null===(t=document.querySelector('meta[name="stripe-publishable-key"]'))||void 0===t?void 0:t.content)&&void 0!==e?e:"",null!==(n=null===(r=document.querySelector('meta[name="stripe-account-id"]'))||void 0===r?void 0:r.content)&&void 0!==n?n:"").setupStripe().handle()})();

View File

@ -37,8 +37,8 @@
"/js/clients/payments/stripe-ideal.js": "/js/clients/payments/stripe-ideal.js?id=188426574f27660936e2",
"/js/clients/payments/stripe-przelewy24.js": "/js/clients/payments/stripe-przelewy24.js?id=e240b907ad163cac04c0",
"/js/clients/payments/stripe-browserpay.js": "/js/clients/payments/stripe-browserpay.js?id=71e49866d66a6d85b88a",
"/js/clients/payments/stripe-fpx.js": "/js/clients/payments/stripe-fpx.js?id=3a1cac8fb671c2e4337f",
"/css/app.css": "/css/app.css?id=daf6d6885d24b59775d5",
"/js/clients/payments/stripe-fpx.js": "/js/clients/payments/stripe-fpx.js?id=765874308d4374726b25",
"/css/app.css": "/css/app.css?id=41b6a44f816ac830ea05",
"/css/card-js.min.css": "/css/card-js.min.css?id=62afeb675235451543ad",
"/vendor/clipboard.min.js": "/vendor/clipboard.min.js?id=ad98572d415d2f245284"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"/livewire.js":"/livewire.js?id=ece4c4ab4b746f6f1739"}
{"/livewire.js":"/livewire.js?id=9a36ebbddb8dd0aa91b1"}

View File

@ -60,11 +60,29 @@ class ProcessFPXPay {
'meta[name="return-url"]'
).content,
}
);
).then((result) => {
if (result.error) {
this.handleFailure(result.error.message);
}
});;
});
};
handleFailure(message) {
let errors = document.getElementById('errors');
errors.textContent = '';
errors.textContent = message;
errors.hidden = false;
document.getElementById('pay-now').disabled = false;
document.querySelector('#pay-now > svg').classList.add('hidden');
document.querySelector('#pay-now > span').classList.remove('hidden');
}
}
const publishableKey = document.querySelector(
'meta[name="stripe-publishable-key"]'
)?.content ?? '';

View File

@ -54,8 +54,6 @@
@include('portal.ninja2020.gateways.includes.save_card')
@include('portal.ninja2020.gateways.wepay.includes.credit_card')
@include('portal.ninja2020.gateways.includes.pay_now')
</form>

View File

@ -14,7 +14,7 @@
@livewire('required-client-info', ['fields' => method_exists($gateway, 'getClientRequiredFields') ? $gateway->getClientRequiredFields() : [], 'contact' => auth()->guard('contact')->user(), 'countries' => $countries, 'company' => $company])
<div class="container mx-auto grid grid-cols-12 opacity-25 pointer-events-none" data-ref="gateway-container">
<div class="col-span-12 lg:col-span-6 lg:col-start-4 overflow-hidden bg-white shadow rounded-lg">
<div class="col-span-12 lg:col-span-6 lg:col-start-4 bg-white shadow rounded-lg">
<div class="px-4 py-5 border-b border-gray-200 sm:px-6">
@isset($card_title)
<h3 class="text-lg font-medium leading-6 text-gray-900">

View File

@ -8,16 +8,28 @@
<span class="page-link">@lang('pagination.previous')</span>
</li>
@else
<li class="page-item">
<button type="button" class="page-link" wire:click="previousPage('{{ $paginator->getPageName() }}')" wire:loading.attr="disabled" rel="prev">@lang('pagination.previous')</button>
</li>
@if(method_exists($paginator,'getCursorName'))
<li class="page-item">
<button dusk="previousPage" type="button" class="page-link" wire:click="setPage('{{$paginator->previousCursor()->encode()}}','{{ $paginator->getCursorName() }}')" wire:loading.attr="disabled" rel="prev">@lang('pagination.previous')</button>
</li>
@else
<li class="page-item">
<button type="button" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}" class="page-link" wire:click="previousPage('{{ $paginator->getPageName() }}')" wire:loading.attr="disabled" rel="prev">@lang('pagination.previous')</button>
</li>
@endif
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<button type="button" class="page-link" wire:click="nextPage('{{ $paginator->getPageName() }}')" wire:loading.attr="disabled" rel="next">@lang('pagination.next')</button>
</li>
@if(method_exists($paginator,'getCursorName'))
<li class="page-item">
<button dusk="nextPage" type="button" class="page-link" wire:click="setPage('{{$paginator->nextCursor()->encode()}}','{{ $paginator->getCursorName() }}')" wire:loading.attr="disabled" rel="next">@lang('pagination.next')</button>
</li>
@else
<li class="page-item">
<button type="button" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}" class="page-link" wire:click="nextPage('{{ $paginator->getPageName() }}')" wire:loading.attr="disabled" rel="next">@lang('pagination.next')</button>
</li>
@endif
@else
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.next')</span>

View File

@ -114,7 +114,7 @@ Route::group(['middleware' => ['invite_db'], 'prefix' => 'client', 'as' => 'clie
Route::get('{entity}/{invitation_key}/download', 'ClientPortal\InvitationController@routerForDownload');
Route::get('pay/{invitation_key}', 'ClientPortal\InvitationController@payInvoice')->name('pay.invoice');
Route::get('unsubscribe/{invitation_key}', 'ClientPortal\InvitationController@unsubscribe')->name('unsubscribe');
Route::get('unsubscribe/{entity_type}/{invitation_key}', 'ClientPortal\InvitationController@unsubscribe')->name('unsubscribe');
// Route::get('{entity}/{client_hash}/{invitation_key}', 'ClientPortal\InvitationController@routerForIframe')->name('invoice.client_hash_and_invitation_key'); //should never need this

View File

@ -377,7 +377,7 @@ class PaymentTest extends TestCase
$this->invoice->company->setRelation('company', $this->company);
$this->invoice->company->setRelation('client', $client);
$this->invoice->save();
$this->invoice->service()->markSent()->save();
$this->invoice->service()->markSent()->createInvitations()->save();
$this->invoice->is_deleted = false;
$this->invoice->save();
@ -457,7 +457,7 @@ class PaymentTest extends TestCase
$this->invoice = $this->invoice_calc->getInvoice();
$this->invoice->save();
$this->invoice->service()->markSent()->save();
$this->invoice->service()->markSent()->createInvitations()->save();
$data = [
'amount' => 2.0,
@ -531,7 +531,7 @@ class PaymentTest extends TestCase
$this->invoice = $this->invoice_calc->getInvoice();
$this->invoice->save();
$this->invoice->service()->markSent()->save();
$this->invoice->service()->markSent()->createInvitations()->save();
$this->invoice->setRelation('client', $client);
@ -579,7 +579,7 @@ class PaymentTest extends TestCase
$this->invoice = $this->invoice_calc->getInvoice();
$this->invoice->save();
$this->invoice->service()->markSent()->save();
$this->invoice->service()->markSent()->createInvitations()->save();
$data = [
'amount' => 2.0,
@ -639,7 +639,7 @@ class PaymentTest extends TestCase
$this->invoice = $this->invoice_calc->getInvoice();
$this->invoice->save();
$this->invoice->service()->markSent()->save();
$this->invoice->service()->markSent()->createInvitations()->save();
$payment = PaymentFactory::create($this->company->id, $this->user->id);
$payment->amount = 10;
@ -692,7 +692,7 @@ class PaymentTest extends TestCase
$this->invoice = $this->invoice_calc->getInvoice();
$this->invoice->save();
$this->invoice->service()->markSent()->save();
$this->invoice->service()->markSent()->createInvitations()->save();
$payment = PaymentFactory::create($this->company->id, $this->user->id);
$payment->amount = 10;
@ -752,7 +752,7 @@ class PaymentTest extends TestCase
$this->invoice = $this->invoice_calc->getInvoice();
$this->invoice->save();
$this->invoice->service()->markSent()->save();
$this->invoice->service()->markSent()->createInvitations()->save();
$data = [
'amount' => 15.0,
@ -803,7 +803,7 @@ class PaymentTest extends TestCase
$this->invoice = $this->invoice_calc->getInvoice();
$this->invoice->save();
$this->invoice->service()->markSent()->save();
$this->invoice->service()->markSent()->createInvitations()->save();
$data = [
'amount' => 15.0,
@ -851,7 +851,7 @@ class PaymentTest extends TestCase
$this->invoice = $this->invoice_calc->getInvoice();
$this->invoice->save();
$this->invoice->service()->markSent()->save();
$this->invoice->service()->markSent()->createInvitations()->save();
$data = [
'amount' => 20.0,
@ -895,7 +895,7 @@ class PaymentTest extends TestCase
// $this->invoice = $this->invoice_calc->getInvoice();
// $this->invoice->save();
// $this->invoice->service()->markSent()->save();
// $this->invoice->service()->markSent()->createInvitations()->save();
// $data = [
// 'amount' => 20.0,
@ -1327,7 +1327,7 @@ class PaymentTest extends TestCase
$this->invoice = $this->invoice_calc->getInvoice();
$this->invoice->save();
$this->invoice->service()->markSent()->save();
$this->invoice->service()->markSent()->createInvitations()->save();
$data = [
'amount' => 20.0,
@ -1422,7 +1422,7 @@ class PaymentTest extends TestCase
$this->invoice = $this->invoice_calc->getInvoice();
$this->invoice->save();
$this->invoice->service()->markSent()->save();
$this->invoice->service()->markSent()->createInvitations()->save();
$this->assertEquals(10, $this->invoice->balance);

View File

@ -79,7 +79,7 @@ class CreditPaymentTest extends TestCase
$invoice = $invoice_calc->getInvoice();
$invoice->setRelation('client', $this->client);
$invoice->setRelation('company', $this->company);
$invoice->service()->markSent()->save();
$invoice->service()->markSent()->createInvitations()->save();
$data = [