mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-10-31 17:18:29 -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