mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-15 23:52:33 +01:00
commit
65e78825fc
@ -1 +1 @@
|
||||
5.2.13
|
||||
5.2.14
|
@ -663,6 +663,7 @@ class CompanySettings extends BaseSettings
|
||||
'$task.line_total',
|
||||
],
|
||||
'total_columns' => [
|
||||
'$net_subtotal',
|
||||
'$subtotal',
|
||||
'$discount',
|
||||
'$custom_surcharge1',
|
||||
|
@ -16,6 +16,7 @@ use App\DataMapper\Analytics\LoginSuccess;
|
||||
use App\Events\User\UserLoggedIn;
|
||||
use App\Http\Controllers\BaseController;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Login\LoginRequest;
|
||||
use App\Jobs\Account\CreateAccount;
|
||||
use App\Jobs\Company\CreateCompanyToken;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
@ -156,7 +157,7 @@ class LoginController extends BaseController
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function apiLogin(Request $request)
|
||||
public function apiLogin(LoginRequest $request)
|
||||
{
|
||||
$this->forced_includes = ['company_users'];
|
||||
|
||||
|
@ -25,7 +25,10 @@ use App\Jobs\Company\CreateCompany;
|
||||
use App\Jobs\Company\CreateCompanyPaymentTerms;
|
||||
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
||||
use App\Jobs\Company\CreateCompanyToken;
|
||||
use App\Jobs\Mail\NinjaMailerJob;
|
||||
use App\Jobs\Mail\NinjaMailerObject;
|
||||
use App\Jobs\Ninja\RefundCancelledAccount;
|
||||
use App\Mail\Company\CompanyDeleted;
|
||||
use App\Models\Account;
|
||||
use App\Models\Company;
|
||||
use App\Models\CompanyUser;
|
||||
@ -505,6 +508,15 @@ class CompanyController extends BaseController
|
||||
$company_user->forceDelete();
|
||||
});
|
||||
|
||||
$other_company = $company->account->companies->where('id', '!=', $company->id)->first();
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new CompanyDeleted($company->present()->name, auth()->user(), $company->account, $company->settings);
|
||||
$nmo->company = $other_company;
|
||||
$nmo->settings = $other_company->settings;
|
||||
$nmo->to_user = auth()->user();
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
|
||||
$company->delete();
|
||||
|
||||
//If we are deleting the default companies, we'll need to make a new company the default.
|
||||
|
@ -35,7 +35,7 @@ class StripeController extends BaseController
|
||||
public function import()
|
||||
{
|
||||
|
||||
return response()->json(['message' => 'Processing'], 200);
|
||||
// return response()->json(['message' => 'Processing'], 200);
|
||||
|
||||
|
||||
if(auth()->user()->isAdmin())
|
||||
|
@ -44,6 +44,14 @@ class PasswordProtection
|
||||
else
|
||||
$timeout = $timeout/1000;
|
||||
|
||||
//test if password if base64 encoded
|
||||
$x_api_password = $request->header('X-API-PASSWORD');
|
||||
|
||||
if($request->header('X-API-PASSWORD-BASE64'))
|
||||
{
|
||||
$x_api_password = base64_decode($request->header('X-API-PASSWORD-BASE64'));
|
||||
}
|
||||
|
||||
if (Cache::get(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in')) {
|
||||
|
||||
Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
|
||||
@ -66,7 +74,7 @@ class PasswordProtection
|
||||
];
|
||||
|
||||
//If OAuth and user also has a password set - check both
|
||||
if ($existing_user = MultiDB::hasUser($query) && auth()->user()->company()->oauth_password_required && auth()->user()->has_password && Hash::check(auth()->user()->password, $request->header('X-API-PASSWORD'))) {
|
||||
if ($existing_user = MultiDB::hasUser($query) && auth()->user()->company()->oauth_password_required && auth()->user()->has_password && Hash::check(auth()->user()->password, $x_api_password)) {
|
||||
|
||||
nlog("existing user with password");
|
||||
|
||||
@ -86,7 +94,7 @@ class PasswordProtection
|
||||
return response()->json($error, 412);
|
||||
|
||||
|
||||
}elseif ($request->header('X-API-PASSWORD') && Hash::check($request->header('X-API-PASSWORD'), auth()->user()->password)) {
|
||||
}elseif ($x_api_password && Hash::check($x_api_password, auth()->user()->password)) {
|
||||
|
||||
Cache::put(auth()->user()->hashed_id.'_'.auth()->user()->account_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
|
@ -144,7 +144,10 @@ class StoreClientRequest extends Request
|
||||
return $item->iso_3166_2 == $country_code || $item->iso_3166_3 == $country_code;
|
||||
})->first();
|
||||
|
||||
if($country)
|
||||
return (string) $country->id;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private function getCurrencyCode($code)
|
||||
|
54
app/Http/Requests/Login/LoginRequest.php
Normal file
54
app/Http/Requests/Login/LoginRequest.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Login;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class LoginRequest extends Request
|
||||
{
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => 'required',
|
||||
'password' => 'required',
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
// if(base64_decode(base64_encode($input['password'])) === $input['password'])
|
||||
// $input['password'] = base64_decode($input['password']);
|
||||
|
||||
// nlog($input['password']);
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
}
|
@ -46,7 +46,7 @@ class ValidRefundableRequest implements Rule
|
||||
return false;
|
||||
}
|
||||
|
||||
$payment = Payment::whereId($this->input['id'])->first();
|
||||
$payment = Payment::whereId($this->input['id'])->withTrashed()->first();
|
||||
|
||||
if (! $payment) {
|
||||
$this->error_msg = ctrans('texts.unable_to_retrieve_payment');
|
||||
@ -77,7 +77,7 @@ class ValidRefundableRequest implements Rule
|
||||
|
||||
private function checkInvoiceIsPaymentable($invoice, $payment)
|
||||
{
|
||||
$invoice = Invoice::whereId($invoice['invoice_id'])->whereCompanyId($payment->company_id)->first();
|
||||
$invoice = Invoice::whereId($invoice['invoice_id'])->whereCompanyId($payment->company_id)->withTrashed()->first();
|
||||
|
||||
if ($payment->invoices()->exists()) {
|
||||
$paymentable_invoice = $payment->invoices->where('id', $invoice->id)->first();
|
||||
|
@ -79,12 +79,14 @@ class CreateAccount
|
||||
|
||||
if(Ninja::isHosted())
|
||||
{
|
||||
|
||||
$sp794f3f->trial_started = now();
|
||||
$sp794f3f->trial_plan = 'pro';
|
||||
// $sp794f3f->plan = 'pro';
|
||||
$sp794f3f->save();
|
||||
|
||||
}
|
||||
|
||||
$sp794f3f->save();
|
||||
|
||||
$sp035a66 = CreateCompany::dispatchNow($this->request, $sp794f3f);
|
||||
$sp035a66->load('account');
|
||||
$sp794f3f->default_company_id = $sp035a66->id;
|
||||
|
@ -1139,7 +1139,10 @@ class Import implements ShouldQueue
|
||||
$payment->save(['timestamps' => false]);
|
||||
|
||||
if (array_key_exists('company_gateway_id', $resource) && isset($resource['company_gateway_id']) && $resource['company_gateway_id'] != 'NULL') {
|
||||
|
||||
if($this->tryTransformingId('company_gateways', $resource['company_gateway_id']))
|
||||
$payment->company_gateway_id = $this->transformId('company_gateways', $resource['company_gateway_id']);
|
||||
|
||||
$payment->save();
|
||||
}
|
||||
|
||||
|
@ -71,9 +71,11 @@ class ReminderJob implements ShouldQueue
|
||||
if ($invoice->isPayable()) {
|
||||
$reminder_template = $invoice->calculateTemplate('invoice');
|
||||
$invoice->service()->touchReminder($reminder_template)->save();
|
||||
|
||||
$invoice = $this->calcLateFee($invoice, $reminder_template);
|
||||
|
||||
//check if this reminder needs to be emailed
|
||||
if(in_array($reminder_template, ['reminder1','reminder2','reminder3']) && $invoice->client->getSetting("enable_".$reminder_template))
|
||||
{
|
||||
$invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) {
|
||||
EmailEntity::dispatch($invitation, $invitation->company, $reminder_template);
|
||||
nlog("Firing reminder email for invoice {$invoice->number}");
|
||||
@ -82,7 +84,7 @@ class ReminderJob implements ShouldQueue
|
||||
if ($invoice->invitations->count() > 0) {
|
||||
event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars(), $reminder_template));
|
||||
}
|
||||
|
||||
}
|
||||
$invoice->service()->setReminder()->save();
|
||||
|
||||
} else {
|
||||
|
@ -115,9 +115,6 @@ class WebhookHandler implements ShouldQueue
|
||||
RequestOptions::JSON => $data, // or 'json' => [...]
|
||||
]);
|
||||
|
||||
if ($response->getStatusCode() == 410 || $response->getStatusCode() == 200)
|
||||
$subscription->delete();
|
||||
|
||||
SystemLogger::dispatch(
|
||||
$response,
|
||||
SystemLog::CATEGORY_WEBHOOK,
|
||||
@ -127,10 +124,13 @@ class WebhookHandler implements ShouldQueue
|
||||
$this->company
|
||||
);
|
||||
|
||||
// if ($response->getStatusCode() == 410 || $response->getStatusCode() == 200)
|
||||
// return true;// $subscription->delete();
|
||||
|
||||
}
|
||||
catch(\Exception $e){
|
||||
|
||||
// nlog($e->getMessage());
|
||||
nlog($e->getMessage());
|
||||
|
||||
SystemLogger::dispatch(
|
||||
$e->getMessage(),
|
||||
@ -143,8 +143,6 @@ class WebhookHandler implements ShouldQueue
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function failed($exception)
|
||||
|
@ -47,8 +47,6 @@ class InvitationViewedListener implements ShouldQueue
|
||||
$entity_name = lcfirst(class_basename($event->entity));
|
||||
$invitation = $event->invitation;
|
||||
|
||||
// $notification = new EntityViewedNotification($invitation, $entity_name);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new NinjaMailer( (new EntityViewedObject($invitation, $entity_name))->build() );
|
||||
$nmo->company = $invitation->company;
|
||||
@ -57,8 +55,9 @@ class InvitationViewedListener implements ShouldQueue
|
||||
|
||||
foreach ($invitation->company->company_users as $company_user) {
|
||||
$entity_viewed = "{$entity_name}_viewed";
|
||||
$entity_viewed_all = "{$entity_name}_viewed_all";
|
||||
|
||||
$methods = $this->findUserNotificationTypes($invitation, $company_user, $entity_name, ['all_notifications', $entity_viewed]);
|
||||
$methods = $this->findUserNotificationTypes($invitation, $company_user, $entity_name, ['all_notifications', $entity_viewed, $entity_viewed_all]);
|
||||
|
||||
if (($key = array_search('mail', $methods)) !== false) {
|
||||
unset($methods[$key]);
|
||||
@ -68,16 +67,7 @@ class InvitationViewedListener implements ShouldQueue
|
||||
|
||||
}
|
||||
|
||||
// $notification->method = $methods;
|
||||
|
||||
// $company_user->user->notify($notification);
|
||||
}
|
||||
|
||||
// if (isset($invitation->company->slack_webhook_url)) {
|
||||
// $notification->method = ['slack'];
|
||||
|
||||
// Notification::route('slack', $invitation->company->slack_webhook_url)
|
||||
// ->notify($notification);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use App\Jobs\Mail\NinjaMailerJob;
|
||||
use App\Jobs\Mail\NinjaMailerObject;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\Admin\VerifyUserObject;
|
||||
use App\Mail\User\UserAdded;
|
||||
use App\Notifications\Ninja\VerifyUser;
|
||||
use App\Utils\Ninja;
|
||||
use Exception;
|
||||
@ -52,5 +53,13 @@ class SendVerificationNotification implements ShouldQueue
|
||||
|
||||
$event->user->service()->invite($event->company);
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new UserAdded($event->company, $event->creating_user, $event->user);
|
||||
$nmo->company = $event->company;
|
||||
$nmo->settings = $event->company->settings;
|
||||
$nmo->to_user = $event->creating_user;
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
61
app/Mail/Company/CompanyDeleted.php
Normal file
61
app/Mail/Company/CompanyDeleted.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Mail\Company;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class CompanyDeleted extends Mailable
|
||||
{
|
||||
// use Queueable, SerializesModels;
|
||||
|
||||
public $account;
|
||||
|
||||
public $company;
|
||||
|
||||
public $user;
|
||||
|
||||
public $settings;
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($company, $user, $account, $settings)
|
||||
{
|
||||
$this->company = $company;
|
||||
$this->user = $user;
|
||||
$this->account = $account;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->from(config('mail.from.address'), config('mail.from.name'))
|
||||
->subject(ctrans('texts.company_deleted'))
|
||||
->view('email.admin.company_deleted')
|
||||
->with([
|
||||
'settings' => $this->settings,
|
||||
'logo' => '',
|
||||
'title' => ctrans('texts.company_deleted'),
|
||||
'body' => ctrans('texts.company_deleted_body', ['company' => $this->company, 'user' => $this->user->present()->name(), 'time' => now()]),
|
||||
'whitelabel' => $this->account->isPaid(),
|
||||
]);
|
||||
}
|
||||
}
|
@ -62,7 +62,7 @@ class SupportMessageSent extends Mailable
|
||||
$user = auth()->user();
|
||||
|
||||
if(Ninja::isHosted())
|
||||
$subject = "{$priority}Hosted-{$company->db} :: Customer Support - [{$plan}] ".date('M jS, g:ia');
|
||||
$subject = "{$priority}Hosted-{$company->db} :: Customer Support - {$plan} ".date('M jS, g:ia');
|
||||
else
|
||||
$subject = "{$priority}Self Hosted :: Customer Support - [{$plan}] ".date('M jS, g:ia');
|
||||
|
||||
|
59
app/Mail/User/UserAdded.php
Normal file
59
app/Mail/User/UserAdded.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Mail\User;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class UserAdded extends Mailable
|
||||
{
|
||||
// use Queueable, SerializesModels;
|
||||
|
||||
public $company;
|
||||
|
||||
public $user;
|
||||
|
||||
public $created_user;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($company, $user, $created_user)
|
||||
{
|
||||
$this->company = $company;
|
||||
$this->user = $user;
|
||||
$this->created_user = $created_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->from(config('mail.from.address'), config('mail.from.name'))
|
||||
->subject(ctrans('texts.created_user'))
|
||||
->view('email.admin.user_added')
|
||||
->with([
|
||||
'settings' => $this->company->settings,
|
||||
'logo' => $this->company->present()->logo(),
|
||||
'title' => ctrans('texts.created_user'),
|
||||
'body' => ctrans('texts.user_created_user', ['user' => $this->user->present()->name(), 'created_user' => $this->created_user->present()->name(), 'time' => now()]),
|
||||
'whitelabel' => $this->company->account->isPaid(),
|
||||
]);
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@ use App\Models\Webhook;
|
||||
|
||||
class InvoiceObserver
|
||||
{
|
||||
public $afterCommit = true;
|
||||
|
||||
/**
|
||||
* Handle the client "created" event.
|
||||
*
|
||||
@ -27,6 +29,7 @@ class InvoiceObserver
|
||||
*/
|
||||
public function created(Invoice $invoice)
|
||||
{
|
||||
|
||||
$subscriptions = Webhook::where('company_id', $invoice->company->id)
|
||||
->where('event_id', Webhook::EVENT_CREATE_INVOICE)
|
||||
->exists();
|
||||
|
@ -283,7 +283,7 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
$fee_total = $this->payment_hash->fee_total;
|
||||
|
||||
/*Hydrate invoices*/
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_invoices, 'invoice_id')))->get();
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_invoices, 'invoice_id')))->withTrashed()->get();
|
||||
|
||||
$invoices->each(function ($invoice) use ($fee_total) {
|
||||
if (collect($invoice->line_items)->contains('type_id', '3')) {
|
||||
@ -303,7 +303,7 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
*/
|
||||
public function unWindGatewayFees(PaymentHash $payment_hash)
|
||||
{
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->get();
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->withTrashed()->get();
|
||||
|
||||
$invoices->each(function ($invoice) {
|
||||
$invoice->service()->removeUnpaidGatewayFees();
|
||||
@ -384,7 +384,7 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
$nmo->company = $gateway->client->company;
|
||||
$nmo->settings = $gateway->client->company->settings;
|
||||
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->get();
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->withTrashed()->get();
|
||||
|
||||
$invoices->each(function ($invoice){
|
||||
|
||||
|
@ -271,7 +271,7 @@ class BasePaymentDriver
|
||||
public function attachInvoices(Payment $payment, PaymentHash $payment_hash): Payment
|
||||
{
|
||||
$paid_invoices = $payment_hash->invoices();
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($paid_invoices, 'invoice_id')))->get();
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($paid_invoices, 'invoice_id')))->withTrashed()->get();
|
||||
$payment->invoices()->sync($invoices);
|
||||
$payment->save();
|
||||
|
||||
@ -300,7 +300,7 @@ class BasePaymentDriver
|
||||
// $invoice_totals = array_sum(array_column($payment_invoices,'amount'));
|
||||
|
||||
/*Hydrate invoices*/
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_invoices, 'invoice_id')))->get();
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payment_invoices, 'invoice_id')))->withTrashed()->get();
|
||||
|
||||
$invoices->each(function ($invoice) use ($fee_total) {
|
||||
if (collect($invoice->line_items)->contains('type_id', '3')) {
|
||||
|
@ -149,7 +149,7 @@ class BraintreePaymentDriver extends BaseDriver
|
||||
{
|
||||
$amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total;
|
||||
|
||||
$invoice = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->first();
|
||||
$invoice = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->withTrashed()->first();
|
||||
|
||||
if ($invoice) {
|
||||
$description = "Invoice {$invoice->number} for {$amount} for client {$this->client->present()->name()}";
|
||||
|
@ -198,7 +198,7 @@ class CheckoutComPaymentDriver extends BaseDriver
|
||||
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
|
||||
{
|
||||
$amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total;
|
||||
$invoice = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->first();
|
||||
$invoice = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->withTrashed()->first();
|
||||
|
||||
if ($invoice) {
|
||||
$description = "Invoice {$invoice->number} for {$amount} for client {$this->client->present()->name()}";
|
||||
|
@ -61,7 +61,7 @@ class CustomPaymentDriver extends BaseDriver
|
||||
|
||||
if (count($this->payment_hash->invoices()) > 0) {
|
||||
$invoice_id = $this->decodePrimaryKey($this->payment_hash->invoices()[0]->invoice_id);
|
||||
$invoice = Invoice::findOrFail($invoice_id);
|
||||
$invoice = Invoice::withTrashed()->find($invoice_id);
|
||||
|
||||
$variables = (new HtmlEngine($invoice->invitations->first()))->generateLabelsAndValues();
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ class CreditCard
|
||||
|
||||
$payment = $this->payfast->createPayment($payment_record, Payment::STATUS_COMPLETED);
|
||||
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->payfast->encodePrimaryKey($payment->id)]);
|
||||
//return redirect()->route('client.payments.show', ['payment' => $this->payfast->encodePrimaryKey($payment->id)]);
|
||||
}
|
||||
|
||||
private function processUnsuccessfulPayment($server_response)
|
||||
|
@ -169,6 +169,7 @@ class PayFastPaymentDriver extends BaseDriver
|
||||
{
|
||||
|
||||
$data = $request->all();
|
||||
nlog("payfast");
|
||||
nlog($data);
|
||||
|
||||
if(array_key_exists('m_payment_id', $data))
|
||||
@ -179,17 +180,23 @@ class PayFastPaymentDriver extends BaseDriver
|
||||
switch ($hash)
|
||||
{
|
||||
case 'cc_auth':
|
||||
return $this->setPaymentMethod(GatewayType::CREDIT_CARD)
|
||||
$this->setPaymentMethod(GatewayType::CREDIT_CARD)
|
||||
->authorizeResponse($request);
|
||||
|
||||
return response()->json([], 200);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
$payment_hash = PaymentHash::whereRaw('BINARY `hash`= ?', [$data['m_payment_id']])->first();
|
||||
|
||||
return $this->setPaymentMethod(GatewayType::CREDIT_CARD)
|
||||
$this->setPaymentMethod(GatewayType::CREDIT_CARD)
|
||||
->setPaymentHash($payment_hash)
|
||||
->processPaymentResponse($request);
|
||||
|
||||
return response()->json([], 200);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -197,36 +197,23 @@ class PayPalExpressPaymentDriver extends BaseDriver
|
||||
|
||||
public function generatePaymentItems(array $data)
|
||||
{
|
||||
$total = 0;
|
||||
|
||||
$items = collect($this->payment_hash->data->invoices)->map(function ($i) use (&$total) {
|
||||
$invoice = Invoice::findOrFail($this->decodePrimaryKey($i->invoice_id));
|
||||
$_invoice = collect($this->payment_hash->data->invoices)->first();
|
||||
$invoice = Invoice::withTrashed()->find($this->decodePrimaryKey($_invoice->invoice_id));
|
||||
|
||||
return collect($invoice->line_items)->map(function ($lineItem) use (&$total) {
|
||||
if (floatval($lineItem->quantity) != intval($lineItem->quantity)) {
|
||||
return null;
|
||||
}
|
||||
$line_item = collect($invoice->line_items)->first();
|
||||
|
||||
$total += $lineItem->cost * $lineItem->quantity;
|
||||
$items = [];
|
||||
|
||||
return new Item([
|
||||
'name' => $lineItem->product_key,
|
||||
'description' => substr(strip_tags($lineItem->notes), 0, 100),
|
||||
'price' => $lineItem->cost,
|
||||
'quantity' => $lineItem->quantity,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
if ($total != $data['total']['amount_with_fee']) {
|
||||
$items[0][] = new Item([
|
||||
'name' => trans('texts.taxes_and_fees'),
|
||||
'description' => '',
|
||||
'price' => $data['total']['amount_with_fee'] - $total,
|
||||
$items[] = new Item([
|
||||
'name' => " ",
|
||||
'description' => ctrans('texts.invoice_number') . "# " . $invoice->number,
|
||||
'price' => $data['total']['amount_with_fee'],
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
return $items;
|
||||
|
||||
}
|
||||
|
||||
return $items[0]->toArray();
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,8 @@ class ACH
|
||||
$customer = $this->stripe->findOrCreateCustomer();
|
||||
|
||||
try {
|
||||
$source = $this->stripe->stripe->customers->createSource($customer->id, ['source' => $stripe_response->token->id]);
|
||||
$source = Customer::createSource($customer->id, ['source' => $stripe_response->token->id], $this->stripe->stripe_connect_auth);
|
||||
// $source = $this->stripe->stripe->customers->createSource($customer->id, ['source' => $stripe_response->token->id]);
|
||||
} catch (InvalidRequestException $e) {
|
||||
throw new PaymentFailed($e->getMessage(), $e->getCode());
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ class Charge
|
||||
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
|
||||
{
|
||||
$amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total;
|
||||
$invoice = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->first();
|
||||
$invoice = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->withTrashed()->first();
|
||||
|
||||
if ($invoice) {
|
||||
$description = "Invoice {$invoice->number} for {$amount} for client {$this->stripe->client->present()->name()}";
|
||||
@ -62,7 +62,6 @@ class Charge
|
||||
|
||||
$this->stripe->init();
|
||||
|
||||
|
||||
$response = null;
|
||||
|
||||
try {
|
||||
@ -75,7 +74,7 @@ class Charge
|
||||
'confirm' => true,
|
||||
'description' => $description,
|
||||
];
|
||||
|
||||
nlog($data);
|
||||
$response = $this->stripe->createPaymentIntent($data, $this->stripe->stripe_connect_auth);
|
||||
// $response = $local_stripe->paymentIntents->create($data);
|
||||
|
||||
|
@ -48,91 +48,99 @@ class UpdateReminder extends AbstractService
|
||||
|
||||
if (is_null($this->invoice->reminder1_sent) &&
|
||||
$this->settings->schedule_reminder1 == 'after_invoice_date' &&
|
||||
$this->settings->num_days_reminder1 > 0) {
|
||||
$this->settings->enable_reminder1) {
|
||||
$reminder_date = Carbon::parse($this->invoice->date)->startOfDay()->addDays($this->settings->num_days_reminder1)->addSeconds($offset);
|
||||
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)));
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)))
|
||||
$date_collection->push($reminder_date);
|
||||
}
|
||||
|
||||
if (is_null($this->invoice->reminder1_sent) &&
|
||||
$this->settings->schedule_reminder1 == 'before_due_date' &&
|
||||
$this->settings->num_days_reminder1 > 0) {
|
||||
$this->settings->enable_reminder1) {
|
||||
$reminder_date = Carbon::parse($this->invoice->due_date)->startOfDay()->subDays($this->settings->num_days_reminder1)->addSeconds($offset);
|
||||
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)));
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)))
|
||||
$date_collection->push($reminder_date);
|
||||
}
|
||||
|
||||
if (is_null($this->invoice->reminder1_sent) &&
|
||||
$this->settings->schedule_reminder1 == 'after_due_date' &&
|
||||
$this->settings->num_days_reminder1 > 0) {
|
||||
$this->settings->enable_reminder1) {
|
||||
$reminder_date = Carbon::parse($this->invoice->due_date)->startOfDay()->addDays($this->settings->num_days_reminder1)->addSeconds($offset);
|
||||
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)));
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)))
|
||||
$date_collection->push($reminder_date);
|
||||
}
|
||||
|
||||
if (is_null($this->invoice->reminder2_sent) &&
|
||||
$this->settings->schedule_reminder2 == 'after_invoice_date' &&
|
||||
$this->settings->num_days_reminder2 > 0) {
|
||||
$this->settings->enable_reminder2) {
|
||||
$reminder_date = Carbon::parse($this->invoice->date)->startOfDay()->addDays($this->settings->num_days_reminder2)->addSeconds($offset);
|
||||
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)));
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)))
|
||||
$date_collection->push($reminder_date);
|
||||
}
|
||||
|
||||
if (is_null($this->invoice->reminder2_sent) &&
|
||||
$this->settings->schedule_reminder2 == 'before_due_date' &&
|
||||
$this->settings->num_days_reminder2 > 0) {
|
||||
$this->settings->enable_reminder2) {
|
||||
$reminder_date = Carbon::parse($this->invoice->due_date)->startOfDay()->subDays($this->settings->num_days_reminder2)->addSeconds($offset);
|
||||
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)));
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)))
|
||||
$date_collection->push($reminder_date);
|
||||
}
|
||||
|
||||
if (is_null($this->invoice->reminder2_sent) &&
|
||||
$this->settings->schedule_reminder2 == 'after_due_date' &&
|
||||
$this->settings->num_days_reminder2 > 0) {
|
||||
$this->settings->enable_reminder2) {
|
||||
$reminder_date = Carbon::parse($this->invoice->due_date)->startOfDay()->addDays($this->settings->num_days_reminder2)->addSeconds($offset);
|
||||
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)));
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)))
|
||||
$date_collection->push($reminder_date);
|
||||
}
|
||||
|
||||
if (is_null($this->invoice->reminder3_sent) &&
|
||||
$this->settings->schedule_reminder3 == 'after_invoice_date' &&
|
||||
$this->settings->num_days_reminder3 > 0) {
|
||||
$this->settings->enable_reminder3) {
|
||||
$reminder_date = Carbon::parse($this->invoice->date)->startOfDay()->addDays($this->settings->num_days_reminder3)->addSeconds($offset);
|
||||
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)));
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)))
|
||||
$date_collection->push($reminder_date);
|
||||
}
|
||||
|
||||
if (is_null($this->invoice->reminder3_sent) &&
|
||||
$this->settings->schedule_reminder3 == 'before_due_date' &&
|
||||
$this->settings->num_days_reminder3 > 0) {
|
||||
$this->settings->enable_reminder3) {
|
||||
$reminder_date = Carbon::parse($this->invoice->due_date)->startOfDay()->subDays($this->settings->num_days_reminder3)->addSeconds($offset);
|
||||
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)));
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)))
|
||||
$date_collection->push($reminder_date);
|
||||
}
|
||||
|
||||
if (is_null($this->invoice->reminder3_sent) &&
|
||||
$this->settings->schedule_reminder3 == 'after_due_date' &&
|
||||
$this->settings->num_days_reminder3 > 0) {
|
||||
$this->settings->enable_reminder3) {
|
||||
$reminder_date = Carbon::parse($this->invoice->due_date)->startOfDay()->addDays($this->settings->num_days_reminder3)->addSeconds($offset);
|
||||
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)));
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)))
|
||||
$date_collection->push($reminder_date);
|
||||
}
|
||||
|
||||
if ($this->invoice->last_sent_date &&
|
||||
(int)$this->settings->endless_reminder_frequency_id > 0) {
|
||||
$reminder_date = $this->addTimeInterval($this->invoice->last_sent_date, (int)$this->settings->endless_reminder_frequency_id)->addSeconds($offset);
|
||||
$this->settings->enable_reminder_endless) {
|
||||
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)));
|
||||
$reminder_date = $this->addTimeInterval($this->invoice->last_sent_date, (int)$this->settings->endless_reminder_frequency_id);
|
||||
|
||||
if($reminder_date){
|
||||
|
||||
$reminder_date->addSeconds($offset);
|
||||
|
||||
if ($reminder_date->gt(Carbon::parse($this->invoice->next_send_date)))
|
||||
$date_collection->push($reminder_date);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($date_collection->count() >=1 && $date_collection->sort()->first()->gte(now()))
|
||||
@ -143,6 +151,20 @@ class UpdateReminder extends AbstractService
|
||||
return $this->invoice;
|
||||
}
|
||||
|
||||
private function testReminderValid($reminder_number, $reminder_schedule) :bool
|
||||
{
|
||||
|
||||
$reminder_sent = "reminder{$reminder_number}_sent";
|
||||
$schedule_reminder = "schedule_reminder{$reminder_number}";
|
||||
$enable_reminder = "enable_reminder{$reminder_number}";
|
||||
$late_fee_amount = "late_fee_amount{$reminder_number}";
|
||||
$late_fee_percent = "late_fee_percent{$reminder_number}";
|
||||
|
||||
return (is_null($this->invoice->{$reminder_sent}) &&
|
||||
$this->settings->{$schedule_reminder} == $reminder_schedule &&
|
||||
($this->settings->{$enable_reminder} || $late_fee_percent > 0 || $late_fee_amount > 0));
|
||||
|
||||
}
|
||||
|
||||
private function addTimeInterval($date, $endless_reminder_frequency_id) :?Carbon
|
||||
{
|
||||
|
@ -51,6 +51,7 @@ class DesignTransformer extends EntityTransformer
|
||||
'archived_at' => (int) $design->deleted_at,
|
||||
'created_at' => (int) $design->created_at,
|
||||
'is_deleted' => (bool) $design->is_deleted,
|
||||
'is_free' => ($design->id <= 4) ? true : false,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +167,7 @@ class HtmlEngine
|
||||
$data['$invoice.discount'] = ['value' => Number::formatMoney($this->entity_calc->getTotalDiscount(), $this->client) ?: ' ', 'label' => ctrans('texts.discount')];
|
||||
$data['$discount'] = &$data['$invoice.discount'];
|
||||
$data['$subtotal'] = ['value' => Number::formatMoney($this->entity_calc->getSubTotal(), $this->client) ?: ' ', 'label' => ctrans('texts.subtotal')];
|
||||
$data['$net_subtotal'] = ['value' => Number::formatMoney(($this->entity_calc->getSubTotal() - $this->entity->total_taxes), $this->client) ?: ' ', 'label' => ctrans('texts.subtotal')];
|
||||
$data['$invoice.subtotal'] = &$data['$subtotal'];
|
||||
|
||||
if ($this->entity->partial > 0) {
|
||||
|
@ -170,4 +170,29 @@ class Ninja
|
||||
|
||||
// return implode('-', $parts);
|
||||
// }
|
||||
//
|
||||
|
||||
/*
|
||||
* Available - but not recommended for use
|
||||
*
|
||||
* This will guarantee a given string IS the correct format for a
|
||||
* base64 encoded string ,
|
||||
* but can't guarantee that it is a base64 encoded string
|
||||
*
|
||||
*/
|
||||
public static function isBase64Encoded(string $s) : bool
|
||||
{
|
||||
|
||||
// Check if there are valid base64 characters
|
||||
if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $s)) return false;
|
||||
// Decode the string in strict mode and check the results
|
||||
$decoded = base64_decode($s, true);
|
||||
if(false === $decoded) return false;
|
||||
// if string returned contains not printable chars
|
||||
if (0 < preg_match('/((?![[:graph:]])(?!\s)(?!\p{L}))./', $decoded, $matched)) return false;
|
||||
// Encode the string again
|
||||
if(base64_encode($decoded) != $s) return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ class SystemHealth
|
||||
'flutter_renderer' => (string)config('ninja.flutter_canvas_kit'),
|
||||
'jobs_pending' => (int) Queue::size(),
|
||||
'pdf_engine' => (string) self::getPdfEngine(),
|
||||
'queue' => (string) config('queue.default'),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,8 @@ return [
|
||||
'require_https' => env('REQUIRE_HTTPS', true),
|
||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||
'app_version' => '5.2.13',
|
||||
'app_tag' => '5.2.13',
|
||||
'app_version' => '5.2.14',
|
||||
'app_tag' => '5.2.14',
|
||||
'minimum_client_version' => '5.0.16',
|
||||
'terms_version' => '1.0.1',
|
||||
'api_secret' => env('API_SECRET', ''),
|
||||
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class SetInvoiceTaskDatelogTrueInCompaniesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('companies', function (Blueprint $table) {
|
||||
$table->boolean('invoice_task_datelog')->default(1)->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
12188
package-lock.json
generated
12188
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
2
public/flutter_service_worker.js
vendored
2
public/flutter_service_worker.js
vendored
@ -4,7 +4,7 @@ const TEMP = 'flutter-temp-cache';
|
||||
const CACHE_NAME = 'flutter-app-cache';
|
||||
const RESOURCES = {
|
||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
|
||||
"main.dart.js": "fea9b4fc231a933ebcf3f80aa8c9eb45",
|
||||
"main.dart.js": "0e2c2fce69f7c2311615c518afa55e3e",
|
||||
"/": "23224b5e03519aaa87594403d54412cf",
|
||||
"manifest.json": "ce1b79950eb917ea619a0a30da27c6a3",
|
||||
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "174c02fc4609e8fc4389f5d21f16a296",
|
||||
|
4
public/main.dart.js
vendored
4
public/main.dart.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
8
public/main.foss.dart.js
vendored
8
public/main.foss.dart.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -4281,6 +4281,9 @@ $LANG = array(
|
||||
'quotes_with_status_sent_can_be_approved' => 'Only quotes with "Sent" status can be approved.',
|
||||
'no_quotes_available_for_download' => 'No quotes available for download.',
|
||||
'copyright' => 'Copyright',
|
||||
'user_created_user' => ':user created :created_user at :time',
|
||||
'company_deleted' => 'Company deleted',
|
||||
'company_deleted_body' => 'Company [ :company ] was deleted by :user',
|
||||
);
|
||||
|
||||
return $LANG;
|
||||
|
6
resources/views/email/admin/company_deleted.blade.php
Normal file
6
resources/views/email/admin/company_deleted.blade.php
Normal file
@ -0,0 +1,6 @@
|
||||
@component('email.template.admin', ['logo' => $logo, 'settings' => $settings])
|
||||
<div class="center">
|
||||
<h1>{!! $title !!}</h1>
|
||||
<p>{!! $body !!}</p>
|
||||
</div>
|
||||
@endcomponent
|
6
resources/views/email/admin/user_added.blade.php
Normal file
6
resources/views/email/admin/user_added.blade.php
Normal file
@ -0,0 +1,6 @@
|
||||
@component('email.template.admin', ['logo' => $logo, 'settings' => $settings])
|
||||
<div class="center">
|
||||
<h1>{!! $title !!}</h1>
|
||||
<p>{!! $body !!}</p>
|
||||
</div>
|
||||
@endcomponent
|
@ -12,6 +12,8 @@
|
||||
|
||||
namespace Tests\Feature\ClientPortal;
|
||||
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Http\Livewire\CreditsTable;
|
||||
use App\Models\Account;
|
||||
use App\Models\Client;
|
||||
@ -19,6 +21,7 @@ use App\Models\ClientContact;
|
||||
use App\Models\Company;
|
||||
use App\Models\Credit;
|
||||
use App\Models\User;
|
||||
use App\Utils\Traits\AppSetup;
|
||||
use Faker\Factory;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Livewire\Livewire;
|
||||
@ -28,12 +31,14 @@ use function now;
|
||||
class CreditsTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
use AppSetup;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->faker = Factory::create();
|
||||
$this->buildCache(true);
|
||||
}
|
||||
|
||||
public function testShowingOnlyCreditsWithDueDateLessOrEqualToNow()
|
||||
@ -45,8 +50,12 @@ class CreditsTest extends TestCase
|
||||
);
|
||||
|
||||
$company = Company::factory()->create(['account_id' => $account->id]);
|
||||
$company->settings = CompanySettings::defaults();
|
||||
$company->save();
|
||||
|
||||
$client = Client::factory()->create(['company_id' => $company->id, 'user_id' => $user->id]);
|
||||
$client->settings = ClientSettings::defaults();
|
||||
$client->save();
|
||||
|
||||
ClientContact::factory()->count(2)->create([
|
||||
'user_id' => $user->id,
|
||||
|
@ -20,6 +20,7 @@ use App\Models\ClientContact;
|
||||
use App\Models\Company;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\User;
|
||||
use App\Utils\Traits\AppSetup;
|
||||
use Faker\Factory;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Livewire\Livewire;
|
||||
@ -28,12 +29,15 @@ use Tests\TestCase;
|
||||
class InvoicesTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
use AppSetup;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->faker = Factory::create();
|
||||
$this->buildCache(true);
|
||||
|
||||
}
|
||||
|
||||
public function testInvoiceTableFilters()
|
||||
|
@ -86,8 +86,12 @@ class ReminderTest extends TestCase
|
||||
{
|
||||
|
||||
$this->invoice->date = now()->subDays(2)->format('Y-m-d');
|
||||
$this->invoice->due_date = Carbon::now()->addDays(30)->format('Y-m-d');
|
||||
|
||||
$this->invoice->due_date = now()->addDays(30)->format('Y-m-d');
|
||||
$this->invoice->reminder1_sent = now()->subDays(1)->format('Y-m-d');
|
||||
$this->invoice->last_sent_date = now()->subDays(1)->format('Y-m-d');
|
||||
$this->invoice->next_send_date = now()->subDays(1)->format('Y-m-d');
|
||||
$this->invoice->reminder2_sent = null;
|
||||
|
||||
$settings = $this->company->settings;
|
||||
$settings->enable_reminder1 = true;
|
||||
|
57
tests/Unit/Base64Test.php
Normal file
57
tests/Unit/Base64Test.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Utils\Ninja;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
class Base64Test extends TestCase
|
||||
{
|
||||
/**
|
||||
* Important consideration with Base64
|
||||
* encoding checks.
|
||||
*
|
||||
* No method can guarantee against false positives.
|
||||
*/
|
||||
public function setUp() :void
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testBadBase64String()
|
||||
{
|
||||
$this->assertFalse(Ninja::isBase64Encoded('x'));
|
||||
}
|
||||
|
||||
public function testCorrectBase64Encoding()
|
||||
{
|
||||
$this->assertTrue(Ninja::isBase64Encoded('MTIzNDU2'));
|
||||
}
|
||||
|
||||
public function testBadBase64StringScenaro1()
|
||||
{
|
||||
$this->assertFalse(Ninja::isBase64Encoded('Matthies'));
|
||||
}
|
||||
|
||||
public function testBadBase64StringScenaro2()
|
||||
{
|
||||
$this->assertFalse(Ninja::isBase64Encoded('Barthels'));
|
||||
}
|
||||
|
||||
public function testBadBase64StringScenaro3()
|
||||
{
|
||||
$this->assertFalse(Ninja::isBase64Encoded('aaa'));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user