1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 21:22:58 +01:00

Merge pull request #7737 from turbo124/v5-develop

Fixes for editing an archived gateway
This commit is contained in:
David Bomba 2022-08-12 09:39:15 +10:00 committed by GitHub
commit 150030e21f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 188 additions and 25 deletions

View File

@ -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();

View File

@ -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()

View File

@ -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}");

View File

@ -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};
}
}

View File

@ -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()

View File

@ -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();
}

View File

@ -181,4 +181,10 @@ class Vendor extends BaseModel
{
return $this->belongsTo(Country::class);
}
public function date_format()
{
return $this->company->date_format();
}
}

View File

@ -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 ?: '',
],
],
]);

View File

@ -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) {

View File

@ -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());

View File

@ -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')];

View File

@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('licenses', function (Blueprint $table) {
$table->unsignedBigInteger('recurring_invoice_id')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
};

View File

@ -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.',

View File

@ -16,7 +16,7 @@
<label for="password" class="input-label">{{ ctrans('texts.password') }}</label>
<input type="password" name="password" id="password"
class="input"
autofocus>
autofocus required>
@error('password')
<div class="validation validation-fail">
{{ $message }}
@ -27,7 +27,7 @@
<label for="password" class="input-label">{{ ctrans('texts.password_confirmation') }}</label>
<input type="password" name="password_confirmation" id="password_confirmation"
class="input"
autofocus>
autofocus required>
@error('password_confirmation')
<div class="validation validation-fail">
{{ $message }}

View File

@ -48,6 +48,89 @@ class ReminderTest extends TestCase
$this->withoutExceptionHandling();
}
public function testForClientTimezoneEdges()
{
$this->invoice->next_send_date = null;
$this->invoice->date = now()->format('Y-m-d');
$this->invoice->due_date = Carbon::now()->addDays(5)->format('Y-m-d');
$this->invoice->save();
$settings = $this->company->settings;
$settings->enable_reminder1 = true;
$settings->schedule_reminder1 = 'before_due_date';
$settings->num_days_reminder1 = 4;
$settings->enable_reminder2 = true;
$settings->schedule_reminder2 = 'before_due_date';
$settings->num_days_reminder2 = 2;
$settings->enable_reminder3 = true;
$settings->schedule_reminder3 = 'after_due_date';
$settings->num_days_reminder3 = 3;
$settings->timezone_id = '15';
$settings->entity_send_time = 8;
$this->client->company->settings = $settings;
$this->client->push();
$client_settings = $settings;
$client_settings->timezone_id = '15';
$client_settings->entity_send_time = 8;
$this->invoice->client->settings = $client_settings;
$this->invoice->push();
$this->invoice = $this->invoice->service()->markSent()->save();
$this->invoice->service()->setReminder($client_settings)->save();
$next_send_date = Carbon::parse($this->invoice->next_send_date);
$calculatedReminderDate = Carbon::parse($this->invoice->due_date)->subDays(4)->addSeconds($this->invoice->client->timezone_offset());
nlog($next_send_date->format('Y-m-d h:i:s'));
nlog($calculatedReminderDate->format('Y-m-d h:i:s'));
$this->travelTo(now()->addDays(1));
$reminder_template = $this->invoice->calculateTemplate('invoice');
$this->assertEquals('reminder1', $reminder_template);
$this->assertTrue($next_send_date->eq($calculatedReminderDate));
$this->invoice->service()->touchReminder($reminder_template)->save();
$this->assertNotNull($this->invoice->last_sent_date);
$this->assertNotNull($this->invoice->reminder1_sent);
$this->assertNotNull($this->invoice->reminder_last_sent);
//calc next send date
$this->invoice->service()->setReminder()->save();
$next_send_date = Carbon::parse($this->invoice->next_send_date);
nlog($next_send_date->format('Y-m-d h:i:s'));
$calculatedReminderDate = Carbon::parse($this->invoice->due_date)->subDays(2)->addSeconds($this->invoice->client->timezone_offset());
$this->assertTrue($next_send_date->eq($calculatedReminderDate));
$this->travelTo(now()->addDays(2));
$reminder_template = $this->invoice->calculateTemplate('invoice');
$this->assertEquals('reminder2', $reminder_template);
$this->invoice->service()->touchReminder($reminder_template)->save();
$this->assertNotNull($this->invoice->reminder2_sent);
$this->invoice->service()->setReminder()->save();
$next_send_date = Carbon::parse($this->invoice->next_send_date);
$calculatedReminderDate = Carbon::parse($this->invoice->due_date)->addDays(3)->addSeconds($this->invoice->client->timezone_offset());
$this->assertTrue($next_send_date->eq($calculatedReminderDate));
nlog($next_send_date->format('Y-m-d h:i:s'));
}
public function testReminderQueryCatchesDate()
{
$this->invoice->next_send_date = now()->format('Y-m-d');
@ -189,4 +272,6 @@ class ReminderTest extends TestCase
$this->assertNotNull($this->invoice->next_send_date);
}
}

View File

@ -90,6 +90,9 @@ class GeneratesCounterTest extends TestCase
$invoice_number = $this->getNextInvoiceNumber($this->client->fresh(), $this->invoice->fresh());
$this->assertEquals($date_formatted.'-0001', $invoice_number);
$this->invoice->number = $invoice_number;
$this->invoice->save();
$invoice_number = $this->getNextInvoiceNumber($this->client->fresh(), $this->invoice->fresh());
$this->assertEquals($date_formatted.'-0002', $invoice_number);
@ -290,10 +293,12 @@ class GeneratesCounterTest extends TestCase
$invoice_number = $this->getNextClientNumber($this->client);
$this->assertEquals($invoice_number, date('Y').'-0001');
$this->assertEquals($invoice_number, date('Y').'-0010');
$this->client->number = $invoice_number;
$this->client->save();
$invoice_number = $this->getNextClientNumber($this->client);
$this->assertEquals($invoice_number, date('Y').'-0002');
$this->assertEquals($invoice_number, date('Y').'-0011');
}
public function testInvoicePadding()