diff --git a/app/Http/Controllers/Traits/VerifiesUserEmail.php b/app/Http/Controllers/Traits/VerifiesUserEmail.php index 715bbad4477d..e6051ec2dcc9 100644 --- a/app/Http/Controllers/Traits/VerifiesUserEmail.php +++ b/app/Http/Controllers/Traits/VerifiesUserEmail.php @@ -17,6 +17,7 @@ use App\Utils\Traits\MakesHash; use App\Utils\Traits\UserSessionAttributes; use Illuminate\Http\RedirectResponse; use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Facades\Validator; /** * Class VerifiesUserEmail. @@ -33,14 +34,12 @@ trait VerifiesUserEmail { $user = User::where('confirmation_code', request()->confirmation_code)->first(); - // if ($user = User::whereRaw("BINARY `confirmation_code`= ?", request()->input('confirmation_code'))->first()) { - if (! $user) { return $this->render('auth.confirmed', ['root' => 'themes', 'message' => ctrans('texts.wrong_confirmation')]); } $user->email_verified_at = now(); - $user->confirmation_code = null; + // $user->confirmation_code = null; //this prevented the form from showing validation errors. $user->save(); if (isset($user->oauth_user_id)) { @@ -64,10 +63,18 @@ trait VerifiesUserEmail { $user = User::where('id', $this->decodePrimaryKey(request()->user_id))->firstOrFail(); - request()->validate([ - 'password' => ['required', 'min:6'], + $validator = Validator::make(request()->all(), [ + //'password' => ['required', 'min:6'], + 'password' => 'min:6|required_with:password_confirmation|same:password_confirmation', + 'password_confirmation' => 'min:6' ]); + if ($validator->fails()) { + return back() + ->withErrors($validator) + ->withInput(); + } + $user->password = Hash::make(request()->password); $user->email_verified_at = now(); diff --git a/app/Http/Livewire/BillingPortalPurchase.php b/app/Http/Livewire/BillingPortalPurchase.php index ebe0ca6c2688..e4cfaaeef984 100644 --- a/app/Http/Livewire/BillingPortalPurchase.php +++ b/app/Http/Livewire/BillingPortalPurchase.php @@ -98,6 +98,8 @@ class BillingPortalPurchase extends Component */ public $payment_method_id; + private $user_coupon; + /** * List of steps that frontend form follows. * @@ -436,32 +438,45 @@ class BillingPortalPurchase extends Component */ public function updateQuantity(string $option): int { + $this->handleCoupon(); + if ($this->quantity == 1 && $option == 'decrement') { + $this->price = $this->price * 1; return $this->quantity; } - if ($this->quantity >= $this->subscription->max_seats_limit && $option == 'increment') { + if ($this->quantity > $this->subscription->max_seats_limit && $option == 'increment') { + $this->price = $this->price * $this->subscription->max_seats_limit; return $this->quantity; } if ($option == 'increment') { $this->quantity++; - $this->price = $this->subscription->promo_price * $this->quantity; + $this->price = $this->price * $this->quantity; return $this->quantity; } $this->quantity--; - $this->price = $this->subscription->promo_price * $this->quantity; + $this->price = $this->price * $this->quantity; return $this->quantity; } public function handleCoupon() { + + if($this->steps['discount_applied']){ + $this->price = $this->subscription->promo_price; + return; + } + if ($this->coupon == $this->subscription->promo_code) { $this->price = $this->subscription->promo_price; + $this->quantity = 1; $this->steps['discount_applied'] = true; } + else + $this->price = $this->subscription->price; } public function passwordlessLogin() diff --git a/app/Jobs/Util/ReminderJob.php b/app/Jobs/Util/ReminderJob.php index 4aef5a9a3a60..877a5b6516ea 100644 --- a/app/Jobs/Util/ReminderJob.php +++ b/app/Jobs/Util/ReminderJob.php @@ -75,6 +75,7 @@ class ReminderJob implements ShouldQueue ->with('invitations')->cursor()->each(function ($invoice) { if ($invoice->isPayable()) { $reminder_template = $invoice->calculateTemplate('invoice'); + nlog("reminder template = {$reminder_template}"); $invoice->service()->touchReminder($reminder_template)->save(); $invoice = $this->calcLateFee($invoice, $reminder_template); @@ -93,6 +94,7 @@ class ReminderJob implements ShouldQueue $invoice->client->getSetting($enabled_reminder) && $invoice->client->getSetting('send_reminders') && (Ninja::isSelfHost() || $invoice->company->account->isPaidHostedClient())) { + $invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) { EmailEntity::dispatch($invitation, $invitation->company, $reminder_template); nlog("Firing reminder email for invoice {$invoice->number}"); diff --git a/app/Models/Client.php b/app/Models/Client.php index 1962fda33806..0d55cce34413 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -370,6 +370,8 @@ class Client extends BaseModel implements HasLocalePreference return $this->settings->{$setting}; } elseif (is_bool($this->settings->{$setting})) { return $this->settings->{$setting}; + } elseif (is_int($this->settings->{$setting})) { //10-08-2022 integer client values are not being passed back! This resolves it. + return $this->settings->{$setting}; } } diff --git a/app/Models/Company.php b/app/Models/Company.php index 15c9b94336e7..bf98f6b418ab 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -405,15 +405,21 @@ class Company extends BaseModel { $languages = Cache::get('languages'); + //build cache and reinit if (! $languages) { $this->buildCache(true); + $languages = Cache::get('languages'); } + //if the cache is still dead, get from DB + if(!$languages && property_exists($this->settings, 'language_id')) + return Language::find($this->settings->language_id); + return $languages->filter(function ($item) { return $item->id == $this->settings->language_id; })->first(); - // return Language::find($this->settings->language_id); + } public function getLocale() diff --git a/app/Models/CompanyGateway.php b/app/Models/CompanyGateway.php index 0942bbf6bcc4..f668d8423f2a 100644 --- a/app/Models/CompanyGateway.php +++ b/app/Models/CompanyGateway.php @@ -413,8 +413,9 @@ class CompanyGateway extends BaseModel public function resolveRouteBinding($value, $field = null) { + return $this - ->where('id', $this->decodePrimaryKey($value))->firstOrFail(); + ->where('id', $this->decodePrimaryKey($value))->withTrashed()->firstOrFail(); } diff --git a/app/Models/Vendor.php b/app/Models/Vendor.php index f267e9201cfa..461c7e7400b5 100644 --- a/app/Models/Vendor.php +++ b/app/Models/Vendor.php @@ -181,4 +181,10 @@ class Vendor extends BaseModel { return $this->belongsTo(Country::class); } + + public function date_format() + { + return $this->company->date_format(); + } + } diff --git a/app/PaymentDrivers/GoCardless/DirectDebit.php b/app/PaymentDrivers/GoCardless/DirectDebit.php index 9204100b87a2..14ecbcc3e831 100644 --- a/app/PaymentDrivers/GoCardless/DirectDebit.php +++ b/app/PaymentDrivers/GoCardless/DirectDebit.php @@ -62,12 +62,12 @@ class DirectDebit implements MethodInterface 'session_token' => $session_token, ]), 'prefilled_customer' => [ - 'given_name' => auth()->guard('contact')->user()->first_name, - 'family_name' => auth()->guard('contact')->user()->last_name, - 'email' => auth()->guard('contact')->user()->email, - 'address_line1' => auth()->guard('contact')->user()->client->address1, - 'city' => auth()->guard('contact')->user()->client->city, - 'postal_code' => auth()->guard('contact')->user()->client->postal_code, + 'given_name' => auth()->guard('contact')->user()->first_name ?: '', + 'family_name' => auth()->guard('contact')->user()->last_name ?: '', + 'email' => auth()->guard('contact')->user()->email ?: '', + 'address_line1' => auth()->guard('contact')->user()->client->address1 ?: '', + 'city' => auth()->guard('contact')->user()->client->city ?: '', + 'postal_code' => auth()->guard('contact')->user()->client->postal_code ?: '', ], ], ]); diff --git a/app/PaymentDrivers/PayTrace/CreditCard.php b/app/PaymentDrivers/PayTrace/CreditCard.php index 99d07915e818..7b5797990f0c 100644 --- a/app/PaymentDrivers/PayTrace/CreditCard.php +++ b/app/PaymentDrivers/PayTrace/CreditCard.php @@ -156,6 +156,7 @@ class CreditCard 'zip' => $this->paytrace->client->postal_code, ]; + return $data; } public function paymentView($data) @@ -192,6 +193,8 @@ class CreditCard 'invoice_id' => $this->harvestInvoiceId(), ]; +nlog($data); + $response = $this->paytrace->gatewayRequest('/v1/transactions/sale/pt_protect', $data); if ($response->success) { diff --git a/app/Utils/Traits/MakesReminders.php b/app/Utils/Traits/MakesReminders.php index 5cc0ceff4ca6..eabecca32747 100644 --- a/app/Utils/Traits/MakesReminders.php +++ b/app/Utils/Traits/MakesReminders.php @@ -21,6 +21,7 @@ trait MakesReminders { public function inReminderWindow($schedule_reminder, $num_days_reminder) { + switch ($schedule_reminder) { case 'after_invoice_date': return Carbon::parse($this->date)->addDays($num_days_reminder)->startOfDay()->eq(Carbon::now()->startOfDay()); diff --git a/app/Utils/VendorHtmlEngine.php b/app/Utils/VendorHtmlEngine.php index eb7585bbd445..7e07796be125 100644 --- a/app/Utils/VendorHtmlEngine.php +++ b/app/Utils/VendorHtmlEngine.php @@ -217,10 +217,10 @@ class VendorHtmlEngine $data['$entity.public_notes'] = &$data['$public_notes']; $data['$notes'] = &$data['$public_notes']; - $data['$purchase_order.custom1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order1', $this->entity->custom_value1, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order1')]; - $data['$purchase_order.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order2', $this->entity->custom_value2, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order2')]; - $data['$purchase_order.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order3', $this->entity->custom_value3, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order3')]; - $data['$purchase_order.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order4', $this->entity->custom_value4, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order4')]; + $data['$purchase_order.custom1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice1', $this->entity->custom_value1, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice1')]; + $data['$purchase_order.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice2', $this->entity->custom_value2, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice2')]; + $data['$purchase_order.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice3', $this->entity->custom_value3, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice3')]; + $data['$purchase_order.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice4', $this->entity->custom_value4, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice4')]; $data['$vendor1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor1', $this->vendor->custom_value1, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor1')]; $data['$vendor2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor2', $this->vendor->custom_value2, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor2')]; diff --git a/database/migrations/2022_08_11_011534_licenses_table_for_self_host.php b/database/migrations/2022_08_11_011534_licenses_table_for_self_host.php new file mode 100644 index 000000000000..8fffec838a07 --- /dev/null +++ b/database/migrations/2022_08_11_011534_licenses_table_for_self_host.php @@ -0,0 +1,30 @@ +unsignedBigInteger('recurring_invoice_id')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +}; diff --git a/lang/en/texts.php b/lang/en/texts.php index 0a6fa29897b3..184dd7b7a385 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -200,7 +200,7 @@ $LANG = array( 'removed_logo' => 'Successfully removed logo', 'sent_message' => 'Successfully sent message', 'invoice_error' => 'Please make sure to select a client and correct any errors', - 'limit_clients' => 'Sorry, this will exceed the limit of :count clients', + 'limit_clients' => 'Sorry, this will exceed the limit of :count clients. Please upgrade to a paid plan.', 'payment_error' => 'There was an error processing your payment. Please try again later.', 'registration_required' => 'Please sign up to email an invoice', 'confirmation_required' => 'Please confirm your email address, :link to resend the confirmation email.', diff --git a/resources/views/themes/ninja2020/auth/confirmation_with_password.blade.php b/resources/views/themes/ninja2020/auth/confirmation_with_password.blade.php index e48908e03570..179349e8861e 100644 --- a/resources/views/themes/ninja2020/auth/confirmation_with_password.blade.php +++ b/resources/views/themes/ninja2020/auth/confirmation_with_password.blade.php @@ -16,7 +16,7 @@ + autofocus required> @error('password')