mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-23 20:00:33 -04:00
commit
f7a3fbeb3b
8
.github/workflows/phpunit.yml
vendored
8
.github/workflows/phpunit.yml
vendored
@ -12,8 +12,8 @@ jobs:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
matrix:
|
||||
operating-system: ['ubuntu-18.04', 'ubuntu-20.04']
|
||||
php-versions: ['7.4','8.0','8.1']
|
||||
operating-system: ['ubuntu-18.04', 'ubuntu-20.04', 'ubuntu-22.04']
|
||||
php-versions: ['8.1']
|
||||
phpunit-versions: ['latest']
|
||||
|
||||
env:
|
||||
@ -107,7 +107,3 @@ jobs:
|
||||
env:
|
||||
DB_PORT: ${{ job.services.mysql.ports[3306] }}
|
||||
PHP_CS_FIXER_IGNORE_ENV: true
|
||||
|
||||
- name: Run php-cs-fixer
|
||||
run: |
|
||||
PHP_CS_FIXER_IGNORE_ENV=1 vendor/bin/php-cs-fixer fix
|
||||
|
@ -1 +1 @@
|
||||
5.5.8
|
||||
5.5.9
|
@ -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();
|
||||
|
@ -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()
|
||||
|
@ -40,7 +40,8 @@ class RecurringInvoicesCron
|
||||
public function handle() : void
|
||||
{
|
||||
/* Get all invoices where the send date is less than NOW + 30 minutes() */
|
||||
nlog('Sending recurring invoices '.Carbon::now()->format('Y-m-d h:i:s'));
|
||||
$start = Carbon::now()->format('Y-m-d h:i:s');
|
||||
nlog('Sending recurring invoices '.$start);
|
||||
|
||||
if (! config('ninja.db.multi_db_enabled')) {
|
||||
$recurring_invoices = RecurringInvoice::where('next_send_date', '<=', now()->toDateTimeString())
|
||||
@ -119,5 +120,8 @@ class RecurringInvoicesCron
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
nlog("Recurring invoice send duration " . $start . " - " . Carbon::now()->format('Y-m-d h:i:s'));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ class NinjaMailerJob implements ShouldQueue
|
||||
$this->nmo->mailable->replyTo($this->company->owner()->email, $this->company->owner()->present()->name());
|
||||
}
|
||||
|
||||
// $this->nmo->mailable->tag($this->company->company_key);
|
||||
$this->nmo->mailable->tag($this->company->company_key);
|
||||
|
||||
//send email
|
||||
try {
|
||||
|
@ -41,7 +41,7 @@ class PaymentFailedMailer implements ShouldQueue
|
||||
|
||||
public ?PaymentHash $payment_hash;
|
||||
|
||||
public string $error;
|
||||
public $error;
|
||||
|
||||
public Company $company;
|
||||
|
||||
@ -55,7 +55,7 @@ class PaymentFailedMailer implements ShouldQueue
|
||||
* @param $company
|
||||
* @param $amount
|
||||
*/
|
||||
public function __construct(?PaymentHash $payment_hash, Company $company, Client $client, string $error)
|
||||
public function __construct(?PaymentHash $payment_hash, Company $company, Client $client, $error)
|
||||
{
|
||||
$this->payment_hash = $payment_hash;
|
||||
$this->client = $client;
|
||||
@ -70,6 +70,10 @@ class PaymentFailedMailer implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if(!is_string($this->error)){
|
||||
$this->error = "Payment failed, no reason given.";
|
||||
}
|
||||
|
||||
//Set DB
|
||||
MultiDB::setDb($this->company->db);
|
||||
App::setLocale($this->client->locale());
|
||||
|
@ -127,7 +127,7 @@ class SendRecurring implements ShouldQueue
|
||||
$invoice->invitations->each(function ($invitation) use ($invoice) {
|
||||
if ($invitation->contact && ! $invitation->contact->trashed() && strlen($invitation->contact->email) >= 1 && $invoice->client->getSetting('auto_email_invoice')) {
|
||||
try {
|
||||
EmailEntity::dispatch($invitation, $invoice->company)->delay(10);
|
||||
EmailEntity::dispatch($invitation, $invoice->company)->delay(rand(10,20));
|
||||
} catch (\Exception $e) {
|
||||
nlog($e->getMessage());
|
||||
}
|
||||
@ -140,13 +140,13 @@ class SendRecurring implements ShouldQueue
|
||||
if ($invoice->client->getSetting('auto_bill_date') == 'on_send_date' && $invoice->auto_bill_enabled) {
|
||||
nlog("attempting to autobill {$invoice->number}");
|
||||
// $invoice->service()->autoBill();
|
||||
AutoBill::dispatch($invoice, $this->db)->delay(20);
|
||||
AutoBill::dispatch($invoice, $this->db)->delay(rand(30,40));
|
||||
|
||||
} elseif ($invoice->client->getSetting('auto_bill_date') == 'on_due_date' && $invoice->auto_bill_enabled) {
|
||||
if ($invoice->due_date && Carbon::parse($invoice->due_date)->startOfDay()->lte(now()->startOfDay())) {
|
||||
nlog("attempting to autobill {$invoice->number}");
|
||||
// $invoice->service()->autoBill();
|
||||
AutoBill::dispatch($invoice, $this->db)->delay(20);
|
||||
AutoBill::dispatch($invoice, $this->db)->delay(rand(30,40));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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}");
|
||||
|
@ -96,12 +96,9 @@ class InvoiceEmailEngine extends BaseEmailEngine
|
||||
|
||||
if (is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0) {
|
||||
$subject_template = $this->template_data['subject'];
|
||||
nlog('subject = template data');
|
||||
} elseif (strlen($this->client->getSetting('email_subject_'.$this->reminder_template)) > 0) {
|
||||
$subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template);
|
||||
nlog('subject = settings var');
|
||||
} else {
|
||||
nlog('subject = default template '.'email_subject_'.$this->reminder_template);
|
||||
$subject_template = EmailTemplateDefaults::getDefaultTemplate('email_subject_'.$this->reminder_template, $this->client->locale());
|
||||
// $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template);
|
||||
}
|
||||
|
@ -115,12 +115,12 @@ class TemplateEmail extends Mailable
|
||||
'company' => $company,
|
||||
'whitelabel' => $this->client->user->account->isPaid() ? true : false,
|
||||
'logo' => $this->company->present()->logo($settings),
|
||||
])
|
||||
->withSymfonyMessage(function ($message) use ($company) {
|
||||
$message->getHeaders()->addTextHeader('Tag', $company->company_key);
|
||||
$message->invitation = $this->invitation;
|
||||
})
|
||||
->tag($company->company_key);
|
||||
]);
|
||||
// ->withSymfonyMessage(function ($message) use ($company) {
|
||||
// $message->getHeaders()->addTextHeader('Tag', $company->company_key);
|
||||
// $message->invitation = $this->invitation;
|
||||
//});
|
||||
// ->tag($company->company_key);
|
||||
|
||||
/*In the hosted platform we need to slow things down a little for Storage to catch up.*/
|
||||
|
||||
|
@ -109,12 +109,12 @@ class VendorTemplateEmail extends Mailable
|
||||
'company' => $this->company,
|
||||
'whitelabel' => $this->vendor->user->account->isPaid() ? true : false,
|
||||
'logo' => $this->company->present()->logo($settings),
|
||||
])
|
||||
->withSymfonyMessage(function ($message) {
|
||||
$message->getHeaders()->addTextHeader('Tag', $this->company->company_key);
|
||||
$message->invitation = $this->invitation;
|
||||
})
|
||||
->tag($this->company->company_key);
|
||||
]);
|
||||
//->withSymfonyMessage(function ($message) {
|
||||
// $message->getHeaders()->addTextHeader('Tag', $this->company->company_key);
|
||||
// $message->invitation = $this->invitation;
|
||||
//});
|
||||
// ->tag($this->company->company_key);
|
||||
|
||||
if(Ninja::isHosted() && $this->invitation){
|
||||
|
||||
|
@ -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};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -73,6 +73,7 @@ class CompanyGateway extends BaseModel
|
||||
// const TYPE_WEPAY = 309;
|
||||
// const TYPE_PAYFAST = 310;
|
||||
// const TYPE_PAYTRACE = 311;
|
||||
// const TYPE_FORTE = 314;
|
||||
|
||||
public $gateway_consts = [
|
||||
'38f2c48af60c7dd69e04248cbb24c36e' => 300,
|
||||
@ -85,6 +86,7 @@ class CompanyGateway extends BaseModel
|
||||
'8fdeed552015b3c7b44ed6c8ebd9e992' => 309,
|
||||
'd6814fc83f45d2935e7777071e629ef9' => 310,
|
||||
'bbd736b3254b0aabed6ad7fda1298c88' => 311,
|
||||
'kivcvjexxvdiyqtj3mju5d6yhpeht2xs' => 314,
|
||||
'65faab2ab6e3223dbe848b1686490baz' => 320,
|
||||
'b9886f9257f0c6ee7c302f1c74475f6c' => 321,
|
||||
'hxd6gwg3ekb9tb3v9lptgx1mqyg69zu9' => 322,
|
||||
@ -308,7 +310,7 @@ class CompanyGateway extends BaseModel
|
||||
if(strlen($fees_and_limits->fee_percent) >=1)
|
||||
$label .= $fees_and_limits->fee_percent . '%';
|
||||
|
||||
if(strlen($fees_and_limits->fee_amount) >=1){
|
||||
if(strlen($fees_and_limits->fee_amount) >=1 && $fees_and_limits->fee_amount > 0){
|
||||
|
||||
if(strlen($label) > 1) {
|
||||
|
||||
@ -411,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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -558,6 +558,10 @@ class RecurringInvoice extends BaseModel
|
||||
case '':
|
||||
return $this->calculateDateFromTerms($date);
|
||||
break;
|
||||
|
||||
case 'on_receipt':
|
||||
return Carbon::Parse($date)->copy();
|
||||
break;
|
||||
|
||||
default:
|
||||
return $this->setDayOfMonth($date, $this->due_date_days);
|
||||
|
@ -100,6 +100,8 @@ class SystemLog extends Model
|
||||
const TYPE_MOLLIE = 312;
|
||||
|
||||
const TYPE_EWAY = 313;
|
||||
|
||||
const TYPE_FORTE = 314;
|
||||
|
||||
const TYPE_SQUARE = 320;
|
||||
|
||||
@ -250,7 +252,9 @@ class SystemLog extends Model
|
||||
case self::TYPE_WEPAY:
|
||||
return 'WePay';
|
||||
case self::TYPE_PAYFAST:
|
||||
return 'Payfast';
|
||||
return "Payfast";
|
||||
case self::TYPE_FORTE:
|
||||
return "Forte";
|
||||
default:
|
||||
return 'undefined';
|
||||
}
|
||||
|
@ -181,4 +181,10 @@ class Vendor extends BaseModel
|
||||
{
|
||||
return $this->belongsTo(Country::class);
|
||||
}
|
||||
|
||||
public function date_format()
|
||||
{
|
||||
return $this->company->date_format();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -431,6 +431,10 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
|
||||
public function sendFailureMail($error)
|
||||
{
|
||||
if(is_object($error)){
|
||||
$error = 'Payment Aborted';
|
||||
}
|
||||
|
||||
if (! is_null($this->payment_hash)) {
|
||||
$this->unWindGatewayFees($this->payment_hash);
|
||||
}
|
||||
|
@ -126,6 +126,17 @@ class BraintreePaymentDriver extends BaseDriver
|
||||
|
||||
return $result->customer;
|
||||
}
|
||||
//12-08-2022 catch when the customer is not created.
|
||||
$data = [
|
||||
'transaction_reference' => null,
|
||||
'transaction_response' => $result,
|
||||
'success' => false,
|
||||
'description' => 'Could not create customer',
|
||||
'code' => 500,
|
||||
];
|
||||
|
||||
SystemLogger::dispatch(['server_response' => $result, 'data' => $data], SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_BRAINTREE, $this->client, $this->client->company);
|
||||
|
||||
}
|
||||
|
||||
public function refund(Payment $payment, $amount, $return_client_response = false)
|
||||
|
@ -20,6 +20,8 @@ use App\Http\Requests\Request;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\PaymentDrivers\FortePaymentDriver;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Models\SystemLog;
|
||||
|
||||
class ACH
|
||||
{
|
||||
@ -129,13 +131,36 @@ class ACH
|
||||
} catch (\Throwable $th) {
|
||||
throw $th;
|
||||
}
|
||||
|
||||
$message = [
|
||||
'server_message' => $response->response->response_desc,
|
||||
'server_response' => $response,
|
||||
'data' => $payment_hash->data,
|
||||
];
|
||||
|
||||
if ($httpcode>299) {
|
||||
SystemLogger::dispatch(
|
||||
$message,
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||
SystemLog::TYPE_FORTE,
|
||||
$this->forte->client,
|
||||
$this->forte->client->company,
|
||||
);
|
||||
$error = Validator::make([], []);
|
||||
$error->getMessageBag()->add('gateway_error', $response->response->response_desc);
|
||||
return redirect('client/invoices')->withErrors($error);
|
||||
}
|
||||
|
||||
SystemLogger::dispatch(
|
||||
$message,
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||
SystemLog::TYPE_FORTE,
|
||||
$this->forte->client,
|
||||
$this->forte->client->company,
|
||||
);
|
||||
|
||||
$data = [
|
||||
'payment_method' => $request->payment_method_id,
|
||||
'payment_type' => PaymentType::ACH,
|
||||
|
@ -21,6 +21,8 @@ use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\PaymentDrivers\FortePaymentDriver;
|
||||
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Models\SystemLog;
|
||||
|
||||
class CreditCard
|
||||
{
|
||||
@ -141,12 +143,36 @@ class CreditCard
|
||||
} catch (\Throwable $th) {
|
||||
throw $th;
|
||||
}
|
||||
|
||||
$message = [
|
||||
'server_message' => $response->response->response_desc,
|
||||
'server_response' => $response,
|
||||
'data' => $payment_hash->data,
|
||||
];
|
||||
|
||||
if ($httpcode>299) {
|
||||
SystemLogger::dispatch(
|
||||
$message,
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||
SystemLog::TYPE_FORTE,
|
||||
$this->forte->client,
|
||||
$this->forte->client->company,
|
||||
);
|
||||
$error = Validator::make([], []);
|
||||
$error->getMessageBag()->add('gateway_error', $response->response->response_desc);
|
||||
return redirect('client/invoices')->withErrors($error);
|
||||
}
|
||||
|
||||
SystemLogger::dispatch(
|
||||
$message,
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||
SystemLog::TYPE_FORTE,
|
||||
$this->forte->client,
|
||||
$this->forte->client->company,
|
||||
);
|
||||
|
||||
$data = [
|
||||
'payment_method' => $request->payment_method_id,
|
||||
'payment_type' => PaymentType::parseCardType(strtolower($request->card_brand)) ?: PaymentType::CREDIT_CARD_OTHER,
|
||||
|
@ -49,7 +49,7 @@ class FortePaymentDriver extends BaseDriver
|
||||
return $types;
|
||||
}
|
||||
|
||||
const SYSTEM_LOG_TYPE = SystemLog::TYPE_STRIPE; //define a constant for your gateway ie TYPE_YOUR_CUSTOM_GATEWAY - set the const in the SystemLog model
|
||||
const SYSTEM_LOG_TYPE = SystemLog::TYPE_FORTE; //define a constant for your gateway ie TYPE_YOUR_CUSTOM_GATEWAY - set the const in the SystemLog model
|
||||
|
||||
public function setPaymentMethod($payment_method_id)
|
||||
{
|
||||
|
@ -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 ?: '',
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
@ -156,7 +156,7 @@ class CreditCard
|
||||
'zip' => $this->paytrace->client->postal_code,
|
||||
];
|
||||
|
||||
nlog($data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function paymentView($data)
|
||||
@ -193,6 +193,8 @@ class CreditCard
|
||||
'invoice_id' => $this->harvestInvoiceId(),
|
||||
];
|
||||
|
||||
nlog($data);
|
||||
|
||||
$response = $this->paytrace->gatewayRequest('/v1/transactions/sale/pt_protect', $data);
|
||||
|
||||
if ($response->success) {
|
||||
|
@ -89,15 +89,11 @@ class PaytracePaymentDriver extends BaseDriver
|
||||
|
||||
public function refund(Payment $payment, $amount, $return_client_response = false)
|
||||
{
|
||||
// $cgt = ClientGatewayToken::where('company_gateway_id', $payment->company_gateway_id)
|
||||
// ->where('gateway_type_id', $payment->gateway_type_id)
|
||||
// ->first();
|
||||
|
||||
$data = [
|
||||
'amount' => $amount,
|
||||
//'customer_id' => $cgt->token,
|
||||
'transaction_id' => $payment->transaction_reference,
|
||||
'integrator_id' => '959195xd1CuC',
|
||||
'integrator_id' => $this->company_gateway->getConfigField('integratorId'),
|
||||
];
|
||||
|
||||
$response = $this->gatewayRequest('/v1/transactions/refund/for_transaction', $data);
|
||||
|
@ -195,8 +195,6 @@ class SquarePaymentDriver extends BaseDriver
|
||||
{
|
||||
$fields = [];
|
||||
|
||||
$fields[] = ['name' => 'client_postal_code', 'label' => ctrans('texts.postal_code'), 'type' => 'text', 'validation' => 'required'];
|
||||
|
||||
if ($this->company_gateway->require_client_name) {
|
||||
$fields[] = ['name' => 'client_name', 'label' => ctrans('texts.client_name'), 'type' => 'text', 'validation' => 'required'];
|
||||
}
|
||||
@ -217,6 +215,7 @@ class SquarePaymentDriver extends BaseDriver
|
||||
if ($this->company_gateway->require_billing_address) {
|
||||
$fields[] = ['name' => 'client_address_line_1', 'label' => ctrans('texts.address1'), 'type' => 'text', 'validation' => 'required'];
|
||||
// $fields[] = ['name' => 'client_address_line_2', 'label' => ctrans('texts.address2'), 'type' => 'text', 'validation' => 'nullable'];
|
||||
$fields[] = ['name' => 'client_postal_code', 'label' => ctrans('texts.postal_code'), 'type' => 'text', 'validation' => 'required'];
|
||||
$fields[] = ['name' => 'client_city', 'label' => ctrans('texts.city'), 'type' => 'text', 'validation' => 'required'];
|
||||
$fields[] = ['name' => 'client_state', 'label' => ctrans('texts.state'), 'type' => 'text', 'validation' => 'required'];
|
||||
$fields[] = ['name' => 'client_country_id', 'label' => ctrans('texts.country'), 'type' => 'text', 'validation' => 'required'];
|
||||
|
@ -167,6 +167,17 @@ class CreditCard
|
||||
$this->stripe->client->company,
|
||||
);
|
||||
|
||||
//If the user has come from a subscription double check here if we need to redirect.
|
||||
//08-08-2022
|
||||
if($payment->invoices()->whereHas('subscription')->exists()){
|
||||
$subscription = $payment->invoices()->first()->subscription;
|
||||
|
||||
if($subscription && array_key_exists('return_url', $subscription->webhook_configuration) && strlen($subscription->webhook_configuration['return_url']) >=1)
|
||||
return redirect($subscription->webhook_configuration['return_url']);
|
||||
|
||||
}
|
||||
//08-08-2022
|
||||
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->stripe->encodePrimaryKey($payment->id)]);
|
||||
}
|
||||
|
||||
|
@ -414,6 +414,7 @@ class HtmlEngine
|
||||
|
||||
$data['$portal_button'] = ['value' => '<a class="button" href="'.$this->contact->getLoginLink().'?client_hash='.$this->client->client_hash.'">'.ctrans('texts.view_client_portal').'</a>', 'label' => ctrans('view_client_portal')];
|
||||
$data['$contact.portal_button'] = &$data['$portal_button'];
|
||||
$data['$portalButton'] = &$data['$portal_button'];
|
||||
|
||||
$data['$contact.custom1'] = ['value' => isset($this->contact) ? $this->contact->custom_value1 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact1')];
|
||||
$data['$contact.custom2'] = ['value' => isset($this->contact) ? $this->contact->custom_value2 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact2')];
|
||||
@ -543,7 +544,6 @@ class HtmlEngine
|
||||
/*Payment Aliases*/
|
||||
$data['$paymentLink'] = &$data['$payment_link'];
|
||||
$data['$payment_url'] = &$data['$payment_link'];
|
||||
$data['$portalButton'] = &$data['$portal_button'];
|
||||
|
||||
$data['$dir'] = ['value' => in_array(optional($this->client->language())->locale, ['ar', 'he']) ? 'rtl' : 'ltr', 'label' => ''];
|
||||
$data['$dir_text_align'] = ['value' => in_array(optional($this->client->language())->locale, ['ar', 'he']) ? 'right' : 'left', 'label' => ''];
|
||||
|
@ -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());
|
||||
|
@ -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')];
|
||||
|
90
composer.lock
generated
90
composer.lock
generated
@ -378,16 +378,16 @@
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.232.2",
|
||||
"version": "3.232.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "390ceb3372ffb9f834694e2bd76a36a78ed7d2ee"
|
||||
"reference": "96fae7f4b2ab11a3eb3fceacef7cb4b12e46b27c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/390ceb3372ffb9f834694e2bd76a36a78ed7d2ee",
|
||||
"reference": "390ceb3372ffb9f834694e2bd76a36a78ed7d2ee",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/96fae7f4b2ab11a3eb3fceacef7cb4b12e46b27c",
|
||||
"reference": "96fae7f4b2ab11a3eb3fceacef7cb4b12e46b27c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -464,9 +464,9 @@
|
||||
"support": {
|
||||
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.232.2"
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.232.3"
|
||||
},
|
||||
"time": "2022-08-04T18:17:49+00:00"
|
||||
"time": "2022-08-08T18:19:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
@ -1165,16 +1165,16 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
"version": "3.3.7",
|
||||
"version": "3.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal.git",
|
||||
"reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a"
|
||||
"reference": "118a360e9437e88d49024f36283c8bcbd76105f5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/9f79d4650430b582f4598fe0954ef4d52fbc0a8a",
|
||||
"reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/118a360e9437e88d49024f36283c8bcbd76105f5",
|
||||
"reference": "118a360e9437e88d49024f36283c8bcbd76105f5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1182,21 +1182,21 @@
|
||||
"doctrine/cache": "^1.11|^2.0",
|
||||
"doctrine/deprecations": "^0.5.3|^1",
|
||||
"doctrine/event-manager": "^1.0",
|
||||
"php": "^7.3 || ^8.0",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"psr/cache": "^1|^2|^3",
|
||||
"psr/log": "^1|^2|^3"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "9.0.0",
|
||||
"jetbrains/phpstorm-stubs": "2022.1",
|
||||
"phpstan/phpstan": "1.7.13",
|
||||
"phpstan/phpstan-strict-rules": "^1.2",
|
||||
"phpunit/phpunit": "9.5.20",
|
||||
"psalm/plugin-phpunit": "0.16.1",
|
||||
"squizlabs/php_codesniffer": "3.7.0",
|
||||
"symfony/cache": "^5.2|^6.0",
|
||||
"symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0",
|
||||
"vimeo/psalm": "4.23.0"
|
||||
"phpstan/phpstan": "1.8.2",
|
||||
"phpstan/phpstan-strict-rules": "^1.3",
|
||||
"phpunit/phpunit": "9.5.21",
|
||||
"psalm/plugin-phpunit": "0.17.0",
|
||||
"squizlabs/php_codesniffer": "3.7.1",
|
||||
"symfony/cache": "^5.4|^6.0",
|
||||
"symfony/console": "^4.4|^5.4|^6.0",
|
||||
"vimeo/psalm": "4.24.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/console": "For helpful console commands such as SQL execution and import of files."
|
||||
@ -1256,7 +1256,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/dbal/issues",
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.3.7"
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.4.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1272,7 +1272,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-06-13T21:43:03+00:00"
|
||||
"time": "2022-08-06T20:35:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
@ -2162,16 +2162,16 @@
|
||||
},
|
||||
{
|
||||
"name": "google/apiclient-services",
|
||||
"version": "v0.260.0",
|
||||
"version": "v0.261.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/googleapis/google-api-php-client-services.git",
|
||||
"reference": "8c519ddfd2458fda02dc10d10b142973e578516a"
|
||||
"reference": "c91c5a694e3b8bca37136b830072a23f2c1250fa"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/8c519ddfd2458fda02dc10d10b142973e578516a",
|
||||
"reference": "8c519ddfd2458fda02dc10d10b142973e578516a",
|
||||
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/c91c5a694e3b8bca37136b830072a23f2c1250fa",
|
||||
"reference": "c91c5a694e3b8bca37136b830072a23f2c1250fa",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2200,9 +2200,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/googleapis/google-api-php-client-services/issues",
|
||||
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.260.0"
|
||||
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.261.0"
|
||||
},
|
||||
"time": "2022-07-31T00:58:12+00:00"
|
||||
"time": "2022-08-08T01:28:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "google/auth",
|
||||
@ -4801,16 +4801,16 @@
|
||||
},
|
||||
{
|
||||
"name": "livewire/livewire",
|
||||
"version": "v2.10.6",
|
||||
"version": "v2.10.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/livewire/livewire.git",
|
||||
"reference": "020ad095cf1239138b097d22b584e2701ec3edfb"
|
||||
"reference": "fa0441bf82f1674beecb3a8ad8a4ae428736ed18"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/livewire/livewire/zipball/020ad095cf1239138b097d22b584e2701ec3edfb",
|
||||
"reference": "020ad095cf1239138b097d22b584e2701ec3edfb",
|
||||
"url": "https://api.github.com/repos/livewire/livewire/zipball/fa0441bf82f1674beecb3a8ad8a4ae428736ed18",
|
||||
"reference": "fa0441bf82f1674beecb3a8ad8a4ae428736ed18",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4862,7 +4862,7 @@
|
||||
"description": "A front-end framework for Laravel.",
|
||||
"support": {
|
||||
"issues": "https://github.com/livewire/livewire/issues",
|
||||
"source": "https://github.com/livewire/livewire/tree/v2.10.6"
|
||||
"source": "https://github.com/livewire/livewire/tree/v2.10.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -4870,7 +4870,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-06-19T02:54:20+00:00"
|
||||
"time": "2022-08-08T13:52:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "microsoft/microsoft-graph",
|
||||
@ -5404,16 +5404,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "2.60.0",
|
||||
"version": "2.61.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"reference": "00a259ae02b003c563158b54fb6743252b638ea6"
|
||||
"reference": "bdf4f4fe3a3eac4de84dbec0738082a862c68ba6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/00a259ae02b003c563158b54fb6743252b638ea6",
|
||||
"reference": "00a259ae02b003c563158b54fb6743252b638ea6",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bdf4f4fe3a3eac4de84dbec0738082a862c68ba6",
|
||||
"reference": "bdf4f4fe3a3eac4de84dbec0738082a862c68ba6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -5502,7 +5502,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-07-27T15:57:48+00:00"
|
||||
"time": "2022-08-06T12:41:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/schema",
|
||||
@ -16041,16 +16041,16 @@
|
||||
},
|
||||
{
|
||||
"name": "spatie/flare-client-php",
|
||||
"version": "1.2.0",
|
||||
"version": "1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/flare-client-php.git",
|
||||
"reference": "86a380f5b1ce839af04a08f1c8f2697184cdf23f"
|
||||
"reference": "b1b974348750925b717fa8c8b97a0db0d1aa40ca"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/flare-client-php/zipball/86a380f5b1ce839af04a08f1c8f2697184cdf23f",
|
||||
"reference": "86a380f5b1ce839af04a08f1c8f2697184cdf23f",
|
||||
"url": "https://api.github.com/repos/spatie/flare-client-php/zipball/b1b974348750925b717fa8c8b97a0db0d1aa40ca",
|
||||
"reference": "b1b974348750925b717fa8c8b97a0db0d1aa40ca",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -16098,7 +16098,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/flare-client-php/issues",
|
||||
"source": "https://github.com/spatie/flare-client-php/tree/1.2.0"
|
||||
"source": "https://github.com/spatie/flare-client-php/tree/1.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -16106,7 +16106,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-05-16T12:13:39+00:00"
|
||||
"time": "2022-08-08T10:10:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/ignition",
|
||||
@ -16707,5 +16707,5 @@
|
||||
"platform-dev": {
|
||||
"php": "^7.4|^8.0"
|
||||
},
|
||||
"plugin-api-version": "2.1.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
@ -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.5.8',
|
||||
'app_tag' => '5.5.8',
|
||||
'app_version' => '5.5.9',
|
||||
'app_tag' => '5.5.9',
|
||||
'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;
|
||||
|
||||
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()
|
||||
{
|
||||
//
|
||||
}
|
||||
};
|
@ -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.',
|
||||
|
6
public/flutter_service_worker.js
vendored
6
public/flutter_service_worker.js
vendored
@ -7,11 +7,11 @@ const RESOURCES = {
|
||||
"canvaskit/profiling/canvaskit.wasm": "95e736ab31147d1b2c7b25f11d4c32cd",
|
||||
"canvaskit/canvaskit.js": "c2b4e5f3d7a3d82aed024e7249a78487",
|
||||
"canvaskit/canvaskit.wasm": "4b83d89d9fecbea8ca46f2f760c5a9ba",
|
||||
"/": "784b9b59de6c49b2fa8bc36999656d6a",
|
||||
"/": "a5608e67957af02b2ae0efbcefc9b26a",
|
||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
|
||||
"main.dart.js": "819a7e0f760429027b88f15315928b59",
|
||||
"main.dart.js": "8f5dcc89d5e7a00c97fa3b155f1cc63c",
|
||||
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
|
||||
"version.json": "c0a4deee2c1337ed484674fb0099de5c",
|
||||
"version.json": "a10748384e57f928f4d2871ac7563faf",
|
||||
"flutter.js": "eb2682e33f25cd8f1fc59011497c35f8",
|
||||
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
|
||||
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
|
||||
|
114845
public/main.dart.js
vendored
114845
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
114059
public/main.foss.dart.js
vendored
114059
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
1004
public/main.profile.dart.js
vendored
1004
public/main.profile.dart.js
vendored
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
{"app_name":"invoiceninja_flutter","version":"5.0.90","build_number":"90","package_name":"invoiceninja_flutter"}
|
||||
{"app_name":"invoiceninja_flutter","version":"5.0.91","build_number":"91","package_name":"invoiceninja_flutter"}
|
@ -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 }}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user