diff --git a/VERSION.txt b/VERSION.txt index 7d5275de2ccd..f84782e2e9f0 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.5.21 \ No newline at end of file +5.5.22 \ No newline at end of file diff --git a/app/Console/Commands/CheckData.php b/app/Console/Commands/CheckData.php index 6349202a7d2d..0f7061f0a9ac 100644 --- a/app/Console/Commands/CheckData.php +++ b/app/Console/Commands/CheckData.php @@ -20,6 +20,7 @@ use App\Models\Client; use App\Models\ClientContact; use App\Models\Company; use App\Models\CompanyLedger; +use App\Models\CompanyUser; use App\Models\Contact; use App\Models\Credit; use App\Models\CreditInvitation; diff --git a/app/DataMapper/CompanySettings.php b/app/DataMapper/CompanySettings.php index ecc93b0d42d1..f99d52ce5d5b 100644 --- a/app/DataMapper/CompanySettings.php +++ b/app/DataMapper/CompanySettings.php @@ -26,6 +26,7 @@ class CompanySettings extends BaseSettings public $auto_archive_invoice = false; // @implemented public $qr_iban = ''; //@implemented + public $besr_id = ''; //@implemented public $lock_invoices = 'off'; //off,when_sent,when_paid //@implemented diff --git a/app/Factory/RecurringExpenseToExpenseFactory.php b/app/Factory/RecurringExpenseToExpenseFactory.php index 1f44a75d5a77..80e1378a9b0a 100644 --- a/app/Factory/RecurringExpenseToExpenseFactory.php +++ b/app/Factory/RecurringExpenseToExpenseFactory.php @@ -44,6 +44,10 @@ class RecurringExpenseToExpenseFactory $expense->payment_date = $recurring_expense->payment_date; $expense->amount = $recurring_expense->amount; $expense->foreign_amount = $recurring_expense->foreign_amount ?: 0; + + //11-09-2022 - we should be tracking the recurring expense!! + $expense->recurring_expense_id = $recurring_expense->id; + // $expense->private_notes = $recurring_expense->private_notes; // $expense->public_notes = $recurring_expense->public_notes; diff --git a/app/Helpers/SwissQr/SwissQrGenerator.php b/app/Helpers/SwissQr/SwissQrGenerator.php index 354b76392190..105b0807119d 100644 --- a/app/Helpers/SwissQr/SwissQrGenerator.php +++ b/app/Helpers/SwissQr/SwissQrGenerator.php @@ -104,16 +104,29 @@ class SwissQrGenerator // Add payment reference // This is what you will need to identify incoming payments. - $referenceNumber = QrBill\Reference\QrPaymentReferenceGenerator::generate( - $this->company->present()->besr_id() ?: '', // You receive this number from your bank (BESR-ID). Unless your bank is PostFinance, in that case use NULL. - $this->invoice->number// A number to match the payment with your internal data, e.g. an invoice number - ); - $qrBill->setPaymentReference( - QrBill\DataGroup\Element\PaymentReference::create( - QrBill\DataGroup\Element\PaymentReference::TYPE_QR, - $referenceNumber - )); + if(strlen($this->company->present()->besr_id()) > 1) + { + $referenceNumber = QrBill\Reference\QrPaymentReferenceGenerator::generate( + $this->company->present()->besr_id() ?: '', // You receive this number from your bank (BESR-ID). Unless your bank is PostFinance, in that case use NULL. + $this->invoice->number// A number to match the payment with your internal data, e.g. an invoice number + ); + + $qrBill->setPaymentReference( + QrBill\DataGroup\Element\PaymentReference::create( + QrBill\DataGroup\Element\PaymentReference::TYPE_QR, + $referenceNumber + )); + + } + else{ + + $qrBill->setPaymentReference( + QrBill\DataGroup\Element\PaymentReference::create( + QrBill\DataGroup\Element\PaymentReference::TYPE_NON + )); + + } // Optionally, add some human-readable information about what the bill is for. $qrBill->setAdditionalInformation( @@ -141,6 +154,8 @@ class SwissQrGenerator nlog($violation); } + nlog($e->getMessage()); + return ''; // return $e->getMessage(); } diff --git a/app/Http/Controllers/EmailController.php b/app/Http/Controllers/EmailController.php index f752c6174e4b..17b3f8ff0a78 100644 --- a/app/Http/Controllers/EmailController.php +++ b/app/Http/Controllers/EmailController.php @@ -131,8 +131,10 @@ class EmailController extends BaseController if(Ninja::isHosted() && !$entity_obj->company->account->account_sms_verified) return response(['message' => 'Please verify your account to send emails.'], 400); - if($entity == 'purchaseOrder' || $entity == 'purchase_order' || $template == 'purchase_order'){ - return $this->sendPurchaseOrder($entity_obj, $data); + nlog($entity); + + if($entity == 'purchaseOrder' || $entity == 'purchase_order' || $template == 'purchase_order' || $entity == 'App\Models\PurchaseOrder'){ + return $this->sendPurchaseOrder($entity_obj, $data, $template); } $entity_obj->invitations->each(function ($invitation) use ($data, $entity_string, $entity_obj, $template) { @@ -183,13 +185,15 @@ class EmailController extends BaseController return $this->itemResponse($entity_obj->fresh()); } - private function sendPurchaseOrder($entity_obj, $data) + private function sendPurchaseOrder($entity_obj, $data, $template) { $this->entity_type = PurchaseOrder::class; $this->entity_transformer = PurchaseOrderTransformer::class; + $data['template'] = $template; + PurchaseOrderEmail::dispatch($entity_obj, $entity_obj->company, $data); return $this->itemResponse($entity_obj); diff --git a/app/Http/Controllers/PreviewPurchaseOrderController.php b/app/Http/Controllers/PreviewPurchaseOrderController.php index e159e02101e2..aeabf41ea549 100644 --- a/app/Http/Controllers/PreviewPurchaseOrderController.php +++ b/app/Http/Controllers/PreviewPurchaseOrderController.php @@ -292,7 +292,7 @@ class PreviewPurchaseOrderController extends BaseController { LightLogs::create(new LivePreview()) ->increment() - ->queue(); + ->batch(); } diff --git a/app/Http/Livewire/RequiredClientInfo.php b/app/Http/Livewire/RequiredClientInfo.php index 349c8391547c..3778834bb665 100644 --- a/app/Http/Livewire/RequiredClientInfo.php +++ b/app/Http/Livewire/RequiredClientInfo.php @@ -14,6 +14,7 @@ namespace App\Http\Livewire; use App\Libraries\MultiDB; use App\Models\ClientContact; +use App\Models\CompanyGateway; use Illuminate\Support\Facades\Validator; use Illuminate\Support\Str; use Livewire\Component; @@ -105,6 +106,8 @@ class RequiredClientInfo extends Component public $company; + public $company_gateway_id; + public function mount() { MultiDB::setDb($this->company->db); @@ -141,6 +144,8 @@ class RequiredClientInfo extends Component 'client_postal_code' => $this->contact->client->postal_code, ]); + //if stripe is enabled, we want to update the customer at this point. + return true; } @@ -150,6 +155,7 @@ class RequiredClientInfo extends Component private function updateClientDetails(array $data): bool { + nlog($this->company->id); $client = []; $contact = []; @@ -172,6 +178,16 @@ class RequiredClientInfo extends Component ->push(); if ($contact_update && $client_update) { + + $cg = CompanyGateway::find($this->company_gateway_id); + + if($cg && $cg->update_details){ + $payment_gateway = $cg->driver($this->client)->init(); + + if(method_exists($payment_gateway, "updateCustomer")) + $payment_gateway->updateCustomer(); + } + return true; } diff --git a/app/Http/Requests/Invoice/StoreInvoiceRequest.php b/app/Http/Requests/Invoice/StoreInvoiceRequest.php index 2cb1535c5bee..9387866e3685 100644 --- a/app/Http/Requests/Invoice/StoreInvoiceRequest.php +++ b/app/Http/Requests/Invoice/StoreInvoiceRequest.php @@ -62,7 +62,7 @@ class StoreInvoiceRequest extends Request $rules['invitations.*.client_contact_id'] = 'distinct'; - $rules['number'] = ['nullable', Rule::unique('invoices')->where('company_id', auth()->user()->company()->id)]; + $rules['number'] = ['bail', 'nullable', Rule::unique('invoices')->where('company_id', auth()->user()->company()->id)]; $rules['project_id'] = ['bail', 'sometimes', new ValidProjectForClient($this->all())]; $rules['is_amount_discount'] = ['boolean']; diff --git a/app/Http/ValidationRules/Account/BlackListRule.php b/app/Http/ValidationRules/Account/BlackListRule.php index 0a2a681f0ff3..17357088001d 100644 --- a/app/Http/ValidationRules/Account/BlackListRule.php +++ b/app/Http/ValidationRules/Account/BlackListRule.php @@ -26,6 +26,7 @@ class BlackListRule implements Rule 'arxxwalls.com', 'superhostforumla.com', 'wnpop.com', + 'dataservices.space', ]; /** diff --git a/app/Import/Providers/BaseImport.php b/app/Import/Providers/BaseImport.php index e63bffe6cbbb..365ee46b37cc 100644 --- a/app/Import/Providers/BaseImport.php +++ b/app/Import/Providers/BaseImport.php @@ -173,18 +173,18 @@ class BaseImport $is_free_hosted_client = $this->company->account->isFreeHostedClient(); $hosted_client_count = $this->company->account->hosted_client_count; + if($this->factory_name == 'App\Factory\ClientFactory' && $is_free_hosted_client && (count($data) > $hosted_client_count)) + { + $this->error_array[$entity_type][] = [ + $entity_type => 'client', + 'error' => 'Error, you are attempting to import more clients than your plan allows', + ]; + + return $count; + } + foreach ($data as $key => $record) { - if($this->factory_name instanceof ClientFactory && $is_free_hosted_client && ($this->company->clients()->count() > $hosted_client_count)) - { - $this->error_array[$entity_type][] = [ - $entity_type => $record, - 'error' => 'Client limit reached', - ]; - - return $count; - } - try { $entity = $this->transformer->transform($record); // $validator = $this->request_name::runFormRequest($entity); diff --git a/app/Jobs/Entity/EmailEntity.php b/app/Jobs/Entity/EmailEntity.php index ce76748a6f6e..c10a9ed9df8f 100644 --- a/app/Jobs/Entity/EmailEntity.php +++ b/app/Jobs/Entity/EmailEntity.php @@ -23,6 +23,7 @@ use App\Models\Activity; use App\Models\Company; use App\Models\CreditInvitation; use App\Models\InvoiceInvitation; +use App\Models\PurchaseOrderInvitation; use App\Models\QuoteInvitation; use App\Models\RecurringInvoiceInvitation; use App\Utils\HtmlEngine; @@ -77,12 +78,12 @@ class EmailEntity implements ShouldQueue $this->invitation = $invitation; - $this->settings = $invitation->contact->client->getMergedSettings(); - $this->entity_string = $this->resolveEntityString(); $this->entity = $invitation->{$this->entity_string}; + $this->settings = $invitation->contact->client->getMergedSettings(); + $this->reminder_template = $reminder_template ?: $this->entity->calculateTemplate($this->entity_string); $this->html_engine = new HtmlEngine($invitation); diff --git a/app/Jobs/PurchaseOrder/PurchaseOrderEmail.php b/app/Jobs/PurchaseOrder/PurchaseOrderEmail.php index aeccc61a723c..0aa6967c147f 100644 --- a/app/Jobs/PurchaseOrder/PurchaseOrderEmail.php +++ b/app/Jobs/PurchaseOrder/PurchaseOrderEmail.php @@ -77,7 +77,12 @@ class PurchaseOrderEmail implements ShouldQueue /* Mark entity sent */ $invitation->purchase_order->service()->markSent()->save(); - $email_builder = (new PurchaseOrderEmailEngine($invitation, 'purchase_order', $this->template_data))->build(); + if(is_array($this->template_data) && array_key_exists('template', $this->template_data)) + $template = $this->template_data['template']; + else + $template = 'purchase_order'; + + $email_builder = (new PurchaseOrderEmailEngine($invitation, $template, $this->template_data))->build(); $nmo = new NinjaMailerObject; $nmo->mailable = new VendorTemplateEmail($email_builder, $invitation->contact, $invitation); @@ -86,7 +91,7 @@ class PurchaseOrderEmail implements ShouldQueue $nmo->to_user = $invitation->contact; $nmo->entity_string = 'purchase_order'; $nmo->invitation = $invitation; - $nmo->reminder_template = 'purchase_order'; + $nmo->reminder_template = 'email_template_purchase_order'; $nmo->entity = $invitation->purchase_order; NinjaMailerJob::dispatch($nmo)->delay(5); diff --git a/app/Libraries/MultiDB.php b/app/Libraries/MultiDB.php index 56f3d1d9ac79..dabc5fc647d2 100644 --- a/app/Libraries/MultiDB.php +++ b/app/Libraries/MultiDB.php @@ -329,6 +329,24 @@ class MultiDB return false; } + public static function findAndSetDbByInappTransactionId($transaction_id) :bool + { + $current_db = config('database.default'); + + foreach (self::$dbs as $db) { + if (Account::on($db)->where('inapp_transaction_id', $transaction_id)->exists()) { + self::setDb($db); + + return true; + } + } + + self::setDB($current_db); + + return false; + } + + public static function findAndSetDbByContactKey($contact_key) :bool { $current_db = config('database.default'); diff --git a/app/Listeners/Subscription/AppStoreRenewSubscription.php b/app/Listeners/Subscription/AppStoreRenewSubscription.php new file mode 100644 index 000000000000..d304b2ebe20a --- /dev/null +++ b/app/Listeners/Subscription/AppStoreRenewSubscription.php @@ -0,0 +1,58 @@ +getSubscriptionId(); //$subscription_id + + MultiDB::findAndSetDbByInappTransactionId($inapp_transaction_id); + + $account = Account::where('inapp_transaction_id', $inapp_transaction_id)->first(); + + if($account->plan_term == 'month') + $account->plan_expires = now()->addMonth(); + elseif($account->plan_term == 'year') + $account->plan_expires = now()->addYear(); + + $account->save(); + + // $server_notification = $event->getServerNotification(); + // $subscription = $event->getSubscription(); + // $subscription_identifier = $event->getSubscriptionIdentifier(); + + } + +} \ No newline at end of file diff --git a/app/Mail/SupportMessageSent.php b/app/Mail/SupportMessageSent.php index 5278d495cf84..7258aa19bf01 100644 --- a/app/Mail/SupportMessageSent.php +++ b/app/Mail/SupportMessageSent.php @@ -8,6 +8,7 @@ use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use LimitIterator; use SplFileObject; +use Illuminate\Support\Carbon; class SupportMessageSent extends Mailable { @@ -72,8 +73,8 @@ class SupportMessageSent extends Mailable $plan_status = ''; - if(Carbon::parse($account->plan_expires)->lt(now())) - $plan_status = 'Plan Expired'; + if($account->plan_expires && Carbon::parse($account->plan_expires)->lt(now())) + $plan_status = 'Plan Expired :: '; if (Ninja::isHosted()) { $subject = "{$priority}Hosted-{$db}-{$is_large}{$platform}{$migrated}{$trial} :: {$plan} :: {$plan_status} ".date('M jS, g:ia'); diff --git a/app/Models/Client.php b/app/Models/Client.php index 5c414e978ae4..7b09fa68f80e 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -613,19 +613,19 @@ class Client extends BaseModel implements HasLocalePreference { $defaults = []; - if (! (array_key_exists('terms', $data) && strlen($data['terms']) > 1)) { + if (! (array_key_exists('terms', $data) && is_string($data['terms']) && strlen($data['terms']) > 1)) { $defaults['terms'] = $this->getSetting($entity_name.'_terms'); } elseif (array_key_exists('terms', $data)) { $defaults['terms'] = $data['terms']; } - if (! (array_key_exists('footer', $data) && strlen($data['footer']) > 1)) { + if (! (array_key_exists('footer', $data) && is_string($data['footer']) && strlen($data['footer']) > 1)) { $defaults['footer'] = $this->getSetting($entity_name.'_footer'); } elseif (array_key_exists('footer', $data)) { $defaults['footer'] = $data['footer']; } - if (strlen($this->public_notes) >= 1) { + if (is_string($this->public_notes) && strlen($this->public_notes) >= 1) { $defaults['public_notes'] = $this->public_notes; } diff --git a/app/Models/Webhook.php b/app/Models/Webhook.php index fb0bb4b73180..da8c142367e2 100644 --- a/app/Models/Webhook.php +++ b/app/Models/Webhook.php @@ -70,6 +70,12 @@ class Webhook extends BaseModel const EVENT_PROJECT_UPDATE = 26; + const EVENT_CREATE_CREDIT = 27; + + const EVENT_UPDATE_CREDIT = 28; + + const EVENT_DELETE_CREDIT = 29; + public static $valid_events = [ self::EVENT_CREATE_CLIENT, self::EVENT_CREATE_INVOICE, @@ -97,6 +103,9 @@ class Webhook extends BaseModel self::EVENT_REMIND_INVOICE, self::EVENT_PROJECT_CREATE, self::EVENT_PROJECT_UPDATE, + self::EVENT_CREATE_CREDIT, + self::EVENT_UPDATE_CREDIT, + self::EVENT_DELETE_CREDIT, ]; protected $fillable = [ diff --git a/app/Observers/CreditObserver.php b/app/Observers/CreditObserver.php index 497e32e6dc82..a60e5f02eb50 100644 --- a/app/Observers/CreditObserver.php +++ b/app/Observers/CreditObserver.php @@ -27,6 +27,13 @@ class CreditObserver */ public function created(Credit $credit) { + $subscriptions = Webhook::where('company_id', $credit->company->id) + ->where('event_id', Webhook::EVENT_CREATE_CREDIT) + ->exists(); + + if ($subscriptions) { + WebhookHandler::dispatch(Webhook::EVENT_CREATE_CREDIT, $credit, $credit->company)->delay(now()->addSeconds(2)); + } } /** @@ -37,6 +44,13 @@ class CreditObserver */ public function updated(Credit $credit) { + $subscriptions = Webhook::where('company_id', $credit->company->id) + ->where('event_id', Webhook::EVENT_UPDATE_CREDIT) + ->exists(); + + if ($subscriptions) { + WebhookHandler::dispatch(Webhook::EVENT_UPDATE_CREDIT, $credit, $credit->company)->delay(now()->addSeconds(2)); + } } /** @@ -47,6 +61,13 @@ class CreditObserver */ public function deleted(Credit $credit) { + $subscriptions = Webhook::where('company_id', $credit->company->id) + ->where('event_id', Webhook::EVENT_DELETE_CREDIT) + ->exists(); + + if ($subscriptions) { + WebhookHandler::dispatch(Webhook::EVENT_DELETE_CREDIT, $credit, $credit->company)->delay(now()->addSeconds(2)); + } } /** diff --git a/app/PaymentDrivers/CheckoutComPaymentDriver.php b/app/PaymentDrivers/CheckoutComPaymentDriver.php index a75e93a007aa..c580eb18b6be 100644 --- a/app/PaymentDrivers/CheckoutComPaymentDriver.php +++ b/app/PaymentDrivers/CheckoutComPaymentDriver.php @@ -34,6 +34,7 @@ use Checkout\CheckoutAuthorizationException; use Checkout\CheckoutDefaultSdk; use Checkout\CheckoutFourSdk; use Checkout\Common\CustomerRequest; +use Checkout\Customers\Four\CustomerRequest as FourCustomerRequest; use Checkout\Environment; use Checkout\Library\Exceptions\CheckoutHttpException; use Checkout\Models\Payments\IdSource; @@ -285,12 +286,31 @@ class CheckoutComPaymentDriver extends BaseDriver $response = $this->gateway->getCustomersClient()->get($this->client->present()->email()); return $response; + } catch (\Exception $e) { - $request = new CustomerRequest(); + + if ($this->is_four_api) { + $request = new FourCustomerRequest(); + } + else{ + $request = new CustomerRequest(); + } + $request->email = $this->client->present()->email(); $request->name = $this->client->present()->name(); + $request->phone = $this->client->present()->phone(); - return $request; + try { + $response = $this->gateway->getCustomersClient()->create($request); + } catch (CheckoutApiException $e) { + // API error + $error_details = $e->error_details; + $http_status_code = isset($e->http_metadata) ? $e->http_metadata->getStatusCode() : null; + } catch (CheckoutAuthorizationException $e) { + // Bad Invalid authorization + } + + return $response; } } diff --git a/app/PaymentDrivers/Stripe/Charge.php b/app/PaymentDrivers/Stripe/Charge.php index d9f7253a4e32..f1dee3019796 100644 --- a/app/PaymentDrivers/Stripe/Charge.php +++ b/app/PaymentDrivers/Stripe/Charge.php @@ -17,11 +17,12 @@ use App\Jobs\Util\SystemLogger; use App\Models\ClientGatewayToken; use App\Models\GatewayType; use App\Models\Invoice; +use App\Models\Payment; use App\Models\PaymentHash; use App\Models\PaymentType; use App\Models\SystemLog; -use App\PaymentDrivers\Stripe\ACH; use App\PaymentDrivers\StripePaymentDriver; +use App\PaymentDrivers\Stripe\ACH; use App\Utils\Ninja; use App\Utils\Traits\MakesHash; use Stripe\Exception\ApiConnectionException; @@ -137,8 +138,10 @@ class Charge if ($cgt->gateway_type_id == GatewayType::SEPA) { $payment_method_type = PaymentType::SEPA; + $status = Payment::STATUS_PENDING; } else { $payment_method_type = $response->charges->data[0]->payment_method_details->card->brand; + $status = Payment::STATUS_COMPLETED; } $data = [ @@ -148,7 +151,7 @@ class Charge 'amount' => $amount, ]; - $payment = $this->stripe->createPayment($data); + $payment = $this->stripe->createPayment($data, $status); $payment->meta = $cgt->meta; $payment->save(); diff --git a/app/PaymentDrivers/Stripe/Jobs/UpdateCustomer.php b/app/PaymentDrivers/Stripe/Jobs/UpdateCustomer.php index a9aadefde559..add84804a95b 100644 --- a/app/PaymentDrivers/Stripe/Jobs/UpdateCustomer.php +++ b/app/PaymentDrivers/Stripe/Jobs/UpdateCustomer.php @@ -58,12 +58,12 @@ class UpdateCustomer implements ShouldQueue $company = Company::where('company_key', $this->company_key)->first(); - if($company->id !== config('ninja.ninja_default_company_id')) - return; - $company_gateway = CompanyGateway::find($this->company_gateway_id); $client = Client::withTrashed()->find($this->client_id); + if(!$company_gateway->update_details) + return; + $stripe = $company_gateway->driver($client)->init(); $customer = $stripe->findOrCreateCustomer(); diff --git a/app/PaymentDrivers/StripePaymentDriver.php b/app/PaymentDrivers/StripePaymentDriver.php index 4c3303f98bce..a46d17ace9c8 100644 --- a/app/PaymentDrivers/StripePaymentDriver.php +++ b/app/PaymentDrivers/StripePaymentDriver.php @@ -511,6 +511,36 @@ class StripePaymentDriver extends BaseDriver } } + public function updateCustomer() + { + if($this->client) + { + + $customer = $this->findOrCreateCustomer(); + //Else create a new record + $data['name'] = $this->client->present()->name(); + $data['phone'] = substr($this->client->present()->phone(), 0, 20); + + $data['address']['line1'] = $this->client->address1; + $data['address']['line2'] = $this->client->address2; + $data['address']['city'] = $this->client->city; + $data['address']['postal_code'] = $this->client->postal_code; + $data['address']['state'] = $this->client->state; + $data['address']['country'] = $this->client->country ? $this->client->country->iso_3166_2 : ''; + + $data['shipping']['name'] = $this->client->present()->name(); + $data['shipping']['address']['line1'] = $this->client->shipping_address1; + $data['shipping']['address']['line2'] = $this->client->shipping_address2; + $data['shipping']['address']['city'] = $this->client->shipping_city; + $data['shipping']['address']['postal_code'] = $this->client->shipping_postal_code; + $data['shipping']['address']['state'] = $this->client->shipping_state; + $data['shipping']['address']['country'] = $this->client->shipping_country ? $this->client->shipping_country->iso_3166_2 : ''; + + \Stripe\Customer::update($customer->id, $data, $this->stripe_connect_auth); + + } + } + public function refund(Payment $payment, $amount, $return_client_response = false) { $this->init(); diff --git a/app/Policies/EntityPolicy.php b/app/Policies/EntityPolicy.php index 08beb1c9d7d4..c7c45f28e9e6 100644 --- a/app/Policies/EntityPolicy.php +++ b/app/Policies/EntityPolicy.php @@ -47,7 +47,7 @@ class EntityPolicy public function edit(User $user, $entity) : bool { return ($user->isAdmin() && $entity->company_id == $user->companyId()) - || ($user->hasPermission('edit_'.strtolower(class_basename($entity))) && $entity->company_id == $user->companyId()) + || ($user->hasPermission('edit_'.strtolower(\Illuminate\Support\Str::snake(class_basename($entity)))) && $entity->company_id == $user->companyId()) || ($user->hasPermission('edit_all') && $entity->company_id == $user->companyId()) || $user->owns($entity) || $user->assigned($entity); @@ -64,7 +64,7 @@ class EntityPolicy public function view(User $user, $entity) : bool { return ($user->isAdmin() && $entity->company_id == $user->companyId()) - || ($user->hasPermission('view_'.strtolower(class_basename($entity))) && $entity->company_id == $user->companyId()) + || ($user->hasPermission('view_'.strtolower(\Illuminate\Support\Str::snake(class_basename($entity)))) && $entity->company_id == $user->companyId()) || ($user->hasPermission('view_all') && $entity->company_id == $user->companyId()) || $user->owns($entity) || $user->assigned($entity); diff --git a/app/Repositories/BaseRepository.php b/app/Repositories/BaseRepository.php index 969bfc57363a..4611774fdc80 100644 --- a/app/Repositories/BaseRepository.php +++ b/app/Repositories/BaseRepository.php @@ -304,7 +304,9 @@ class BaseRepository if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) { - //10-07-2022 + //14-09-2022 log when we make changes to the invoice balance. + nlog("Adjustment - {$model->number} - " .$state['finished_amount']. " - " . $state['starting_amount']); + $model->service()->updateStatus()->save(); $model->client->service()->updateBalance(($state['finished_amount'] - $state['starting_amount']))->save(); $model->ledger()->updateInvoiceBalance(($state['finished_amount'] - $state['starting_amount']), "Update adjustment for invoice {$model->number}"); diff --git a/app/Repositories/InvoiceRepository.php b/app/Repositories/InvoiceRepository.php index 3c60618501b1..eea2ae5ffb58 100644 --- a/app/Repositories/InvoiceRepository.php +++ b/app/Repositories/InvoiceRepository.php @@ -68,7 +68,6 @@ class InvoiceRepository extends BaseRepository return $invoice; } -// $invoice->service()->markDeleted()->handleCancellation()->save(); $invoice = $invoice->service()->markDeleted()->save(); parent::delete($invoice); diff --git a/app/Repositories/TaskRepository.php b/app/Repositories/TaskRepository.php index 386a9fd2c8c2..8acf1ec73dfb 100644 --- a/app/Repositories/TaskRepository.php +++ b/app/Repositories/TaskRepository.php @@ -14,6 +14,7 @@ namespace App\Repositories; use App\Factory\TaskFactory; use App\Models\Task; use App\Utils\Traits\GeneratesCounter; +use Illuminate\Database\QueryException; /** * TaskRepository. @@ -45,7 +46,7 @@ class TaskRepository extends BaseRepository $this->setDefaultStatus($task); } - $task->number = empty($task->number) || ! array_key_exists('number', $data) ? $this->getNextTaskNumber($task) : $data['number']; + $task->number = empty($task->number) || ! array_key_exists('number', $data) ? $this->trySaving($task) : $data['number']; if (isset($data['description'])) { $task->description = trim($data['description']); @@ -244,4 +245,34 @@ class TaskRepository extends BaseRepository return $task; } + + + private function trySaving(Task $task) + { + + $x=1; + + do{ + + try{ + + $task->number = $this->getNextTaskNumber($task); + $task->saveQuietly(); + $this->completed = false; + + } + catch(QueryException $e){ + + $x++; + + if($x>50) + $this->completed = false; + } + + } + while($this->completed); + + return $task->number; + + } } diff --git a/app/Services/Client/ClientService.php b/app/Services/Client/ClientService.php index 9e9c5fbf9579..a4d033c34559 100644 --- a/app/Services/Client/ClientService.php +++ b/app/Services/Client/ClientService.php @@ -33,7 +33,7 @@ class ClientService \DB::connection(config('database.default'))->transaction(function () use($amount) { - $this->client = Client::where('id', $this->client->id)->lockForUpdate()->first(); + $this->client = Client::withTrashed()->where('id', $this->client->id)->lockForUpdate()->first(); $this->client->balance += $amount; $this->client->save(); @@ -49,7 +49,7 @@ class ClientService \DB::connection(config('database.default'))->transaction(function () use($balance, $paid_to_date) { - $this->client = Client::where('id', $this->client->id)->lockForUpdate()->first(); + $this->client = Client::withTrashed()->where('id', $this->client->id)->lockForUpdate()->first(); $this->client->balance += $balance; $this->client->paid_to_date += $paid_to_date; $this->client->save(); @@ -65,7 +65,7 @@ class ClientService \DB::connection(config('database.default'))->transaction(function () use($amount) { - $this->client = Client::where('id', $this->client->id)->lockForUpdate()->first(); + $this->client = Client::withTrashed()->where('id', $this->client->id)->lockForUpdate()->first(); $this->client->paid_to_date += $amount; $this->client->save(); @@ -83,7 +83,7 @@ class ClientService public function getCreditBalance() :float { - $credits = Credit::where('client_id', $this->client->id) + $credits = Credit::withTrashed()->where('client_id', $this->client->id) ->where('is_deleted', false) ->where('balance', '>', 0) ->where(function ($query) { diff --git a/app/Services/Invoice/ApplyNumber.php b/app/Services/Invoice/ApplyNumber.php index 58b976eb2b86..d71faf7c73ae 100644 --- a/app/Services/Invoice/ApplyNumber.php +++ b/app/Services/Invoice/ApplyNumber.php @@ -70,7 +70,6 @@ class ApplyNumber extends AbstractService $this->invoice->saveQuietly(); $this->completed = false; - } catch(QueryException $e){ @@ -84,5 +83,8 @@ class ApplyNumber extends AbstractService } while($this->completed); + + return $this; } + } diff --git a/app/Services/Invoice/MarkPaid.php b/app/Services/Invoice/MarkPaid.php index 9c60591515f6..60182238642c 100644 --- a/app/Services/Invoice/MarkPaid.php +++ b/app/Services/Invoice/MarkPaid.php @@ -55,7 +55,7 @@ class MarkPaid extends AbstractService \DB::connection(config('database.default'))->transaction(function () { - $this->invoice = Invoice::where('id', $this->invoice->id)->lockForUpdate()->first(); + $this->invoice = Invoice::withTrashed()->where('id', $this->invoice->id)->lockForUpdate()->first(); $this->payable_balance = $this->invoice->balance; diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php index d9141493f4f4..dae1e0f8ad25 100644 --- a/app/Utils/HtmlEngine.php +++ b/app/Utils/HtmlEngine.php @@ -168,7 +168,7 @@ class HtmlEngine $data['$invoice.vendor'] = ['value' => $this->entity->vendor->present()->name(), 'label' => ctrans('texts.vendor_name')]; } - if(strlen($this->company->getSetting('qr_iban')) > 5 && strlen($this->company->getSetting('besr_id')) > 1) + if(strlen($this->company->getSetting('qr_iban')) > 5) { try{ $data['$swiss_qr'] = ['value' => (new SwissQrGenerator($this->entity, $this->company))->run(), 'label' => '']; diff --git a/app/Utils/Traits/GeneratesCounter.php b/app/Utils/Traits/GeneratesCounter.php index 4175acbe55e9..2debb8ac9647 100644 --- a/app/Utils/Traits/GeneratesCounter.php +++ b/app/Utils/Traits/GeneratesCounter.php @@ -412,26 +412,30 @@ trait GeneratesCounter * @param string $prefix * @return string The padded and prefixed entity number */ - private function checkEntityNumber($class, $entity, $counter, $padding, $pattern, $prefix = '') + private function checkEntityNumber($class, $entity, $counter, $padding, $pattern, $prefix = '') :string { $check = false; $check_counter = 1; do { + $number = $this->padCounter($counter, $padding); $number = $this->applyNumberPattern($entity, $number, $pattern); $number = $this->prefixCounter($number, $prefix); - $check = $class::whereCompanyId($entity->company_id)->whereNumber($number)->withTrashed()->exists(); + $check = $class::where('company_id', $entity->company_id)->where('number', $number)->withTrashed()->exists(); $counter++; $check_counter++; if ($check_counter > 100) { + return $number.'_'.Str::random(5); + } + } while ($check); return $number; diff --git a/composer.json b/composer.json index da1207a62b31..db974d3876dd 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ "authorizenet/authorizenet": "^2.0", "awobaz/compoships": "^2.1", "bacon/bacon-qr-code": "^2.0", - "beganovich/snappdf": "^2", + "beganovich/snappdf": "^3", "braintree/braintree_php": "^6.0", "checkout/checkout-sdk-php": "^2.5", "cleverit/ubl_invoice": "^1.3", @@ -57,7 +57,7 @@ "intervention/image": "^2.5", "invoiceninja/inspector": "^1.0", "laracasts/presenter": "^0.2.1", - "laravel/framework": "^9.17", + "laravel/framework": "^9.3", "laravel/slack-notification-channel": "^2.2", "laravel/socialite": "^5", "laravel/tinker": "^2.7", diff --git a/composer.lock b/composer.lock index 725da7645b19..2a1246227db9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8d9b065d1cf3f4fd42565e77e63c53fc", + "content-hash": "9dc581f41118f9f990e06f938c842839", "packages": [ { "name": "afosto/yaac", @@ -378,16 +378,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.235.3", + "version": "3.235.8", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "d14bf468240f5bd8a0754b8a8248ff219ebada02" + "reference": "cc33d53d735a3835adff212598f2a20ee9ac9531" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/d14bf468240f5bd8a0754b8a8248ff219ebada02", - "reference": "d14bf468240f5bd8a0754b8a8248ff219ebada02", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/cc33d53d735a3835adff212598f2a20ee9ac9531", + "reference": "cc33d53d735a3835adff212598f2a20ee9ac9531", "shasum": "" }, "require": { @@ -406,6 +406,7 @@ "aws/aws-php-sns-message-validator": "~1.0", "behat/behat": "~3.0", "composer/composer": "^1.10.22", + "dms/phpunit-arraysubset-asserts": "^0.4.0", "doctrine/cache": "~1.4", "ext-dom": "*", "ext-openssl": "*", @@ -413,10 +414,11 @@ "ext-sockets": "*", "nette/neon": "^2.3", "paragonie/random_compat": ">= 2", - "phpunit/phpunit": "^4.8.35 || ^5.6.3", + "phpunit/phpunit": "^4.8.35 || ^5.6.3 || ^9.5", "psr/cache": "^1.0", "psr/simple-cache": "^1.0", - "sebastian/comparator": "^1.2.3" + "sebastian/comparator": "^1.2.3 || ^4.0", + "yoast/phpunit-polyfills": "^1.0" }, "suggest": { "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", @@ -464,9 +466,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.235.3" + "source": "https://github.com/aws/aws-sdk-php/tree/3.235.8" }, - "time": "2022-09-07T18:17:39+00:00" + "time": "2022-09-14T18:18:31+00:00" }, { "name": "bacon/bacon-qr-code", @@ -524,16 +526,16 @@ }, { "name": "beganovich/snappdf", - "version": "v2.2.0", + "version": "v3.1.0", "source": { "type": "git", "url": "https://github.com/beganovich/snappdf.git", - "reference": "7964d03c091f3a30513fb6c44ea353c575ba523a" + "reference": "b2656c2c67be086b535cd13a704e27caaf5a7570" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/beganovich/snappdf/zipball/7964d03c091f3a30513fb6c44ea353c575ba523a", - "reference": "7964d03c091f3a30513fb6c44ea353c575ba523a", + "url": "https://api.github.com/repos/beganovich/snappdf/zipball/b2656c2c67be086b535cd13a704e27caaf5a7570", + "reference": "b2656c2c67be086b535cd13a704e27caaf5a7570", "shasum": "" }, "require": { @@ -570,9 +572,9 @@ "description": "Convert webpages or HTML into the PDF file using Chromium or Google Chrome.", "support": { "issues": "https://github.com/beganovich/snappdf/issues", - "source": "https://github.com/beganovich/snappdf/tree/v2.2.0" + "source": "https://github.com/beganovich/snappdf/tree/v3.1.0" }, - "time": "2022-06-29T13:08:15+00:00" + "time": "2022-09-14T10:35:47+00:00" }, { "name": "braintree/braintree_php", @@ -1577,16 +1579,16 @@ }, { "name": "dragonmantank/cron-expression", - "version": "v3.3.1", + "version": "v3.3.2", "source": { "type": "git", "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" + "reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", - "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/782ca5968ab8b954773518e9e49a6f892a34b2a8", + "reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8", "shasum": "" }, "require": { @@ -1626,7 +1628,7 @@ ], "support": { "issues": "https://github.com/dragonmantank/cron-expression/issues", - "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.2" }, "funding": [ { @@ -1634,7 +1636,7 @@ "type": "github" } ], - "time": "2022-01-18T15:43:28+00:00" + "time": "2022-09-10T18:51:20+00:00" }, { "name": "egulias/email-validator", @@ -2162,16 +2164,16 @@ }, { "name": "google/apiclient-services", - "version": "v0.265.0", + "version": "v0.266.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "a23754daa452e26a8dd31a7848863c67a2e3d67e" + "reference": "27ead5edc8ba4a17ddd211ad03216c313a57411f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/a23754daa452e26a8dd31a7848863c67a2e3d67e", - "reference": "a23754daa452e26a8dd31a7848863c67a2e3d67e", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/27ead5edc8ba4a17ddd211ad03216c313a57411f", + "reference": "27ead5edc8ba4a17ddd211ad03216c313a57411f", "shasum": "" }, "require": { @@ -2200,9 +2202,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.265.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.266.0" }, - "time": "2022-09-04T00:58:12+00:00" + "time": "2022-09-12T01:28:14+00:00" }, { "name": "google/auth", @@ -3481,16 +3483,16 @@ }, { "name": "laravel/framework", - "version": "v9.28.0", + "version": "v9.30.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "396a89e1f3654123d1c7f56306051212e5c75bc0" + "reference": "2ca2b168a3e995a8ec6ea2805906379095d20080" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/396a89e1f3654123d1c7f56306051212e5c75bc0", - "reference": "396a89e1f3654123d1c7f56306051212e5c75bc0", + "url": "https://api.github.com/repos/laravel/framework/zipball/2ca2b168a3e995a8ec6ea2805906379095d20080", + "reference": "2ca2b168a3e995a8ec6ea2805906379095d20080", "shasum": "" }, "require": { @@ -3567,12 +3569,15 @@ "illuminate/view": "self.version" }, "require-dev": { + "ably/ably-php": "^1.0", "aws/aws-sdk-php": "^3.198.1", "doctrine/dbal": "^2.13.3|^3.1.4", "fakerphp/faker": "^1.9.2", "guzzlehttp/guzzle": "^7.2", "league/flysystem-aws-s3-v3": "^3.0", "league/flysystem-ftp": "^3.0", + "league/flysystem-path-prefixing": "^3.3", + "league/flysystem-read-only": "^3.3", "league/flysystem-sftp-v3": "^3.0", "mockery/mockery": "^1.4.4", "orchestra/testbench-core": "^7.1", @@ -3600,6 +3605,8 @@ "laravel/tinker": "Required to use the tinker console command (^2.0).", "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", + "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.3).", + "league/flysystem-read-only": "Required to use read-only disks (^3.3)", "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", "mockery/mockery": "Required to use mocking (^1.4.4).", "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", @@ -3657,20 +3664,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-09-06T14:57:01+00:00" + "time": "2022-09-13T14:06:14+00:00" }, { "name": "laravel/serializable-closure", - "version": "v1.2.1", + "version": "v1.2.2", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "d78fd36ba031a1a695ea5a406f29996948d7011b" + "reference": "47afb7fae28ed29057fdca37e16a84f90cc62fae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/d78fd36ba031a1a695ea5a406f29996948d7011b", - "reference": "d78fd36ba031a1a695ea5a406f29996948d7011b", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/47afb7fae28ed29057fdca37e16a84f90cc62fae", + "reference": "47afb7fae28ed29057fdca37e16a84f90cc62fae", "shasum": "" }, "require": { @@ -3717,7 +3724,7 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2022-08-26T15:25:27+00:00" + "time": "2022-09-08T13:45:54+00:00" }, { "name": "laravel/slack-notification-channel", @@ -4387,16 +4394,16 @@ }, { "name": "league/flysystem", - "version": "3.2.1", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "81aea9e5217084c7850cd36e1587ee4aad721c6b" + "reference": "d8295793b3e2f91aa39e1feb2d5bfce772891ae2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/81aea9e5217084c7850cd36e1587ee4aad721c6b", - "reference": "81aea9e5217084c7850cd36e1587ee4aad721c6b", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/d8295793b3e2f91aa39e1feb2d5bfce772891ae2", + "reference": "d8295793b3e2f91aa39e1feb2d5bfce772891ae2", "shasum": "" }, "require": { @@ -4407,6 +4414,7 @@ "aws/aws-sdk-php": "3.209.31 || 3.210.0", "guzzlehttp/guzzle": "<7.0", "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", "symfony/http-client": "<5.2" }, "require-dev": { @@ -4420,7 +4428,7 @@ "friendsofphp/php-cs-fixer": "^3.5", "google/cloud-storage": "^1.23", "microsoft/azure-storage-blob": "^1.1", - "phpseclib/phpseclib": "^2.0", + "phpseclib/phpseclib": "^3.0.14", "phpstan/phpstan": "^0.12.26", "phpunit/phpunit": "^9.5.11", "sabre/dav": "^4.3.1" @@ -4457,11 +4465,11 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.2.1" + "source": "https://github.com/thephpleague/flysystem/tree/3.3.0" }, "funding": [ { - "url": "https://offset.earth/frankdejonge", + "url": "https://ecologi.com/frankdejonge", "type": "custom" }, { @@ -4473,20 +4481,20 @@ "type": "tidelift" } ], - "time": "2022-08-14T20:48:34+00:00" + "time": "2022-09-09T11:11:42+00:00" }, { "name": "league/flysystem-aws-s3-v3", - "version": "3.2.0", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git", - "reference": "257893ef7398b3c9255b26dff8b0118bb93fc5ff" + "reference": "c9402e0b8d89d36b1b88ecf88c2a80b6d61fd114" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/257893ef7398b3c9255b26dff8b0118bb93fc5ff", - "reference": "257893ef7398b3c9255b26dff8b0118bb93fc5ff", + "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/c9402e0b8d89d36b1b88ecf88c2a80b6d61fd114", + "reference": "c9402e0b8d89d36b1b88ecf88c2a80b6d61fd114", "shasum": "" }, "require": { @@ -4527,11 +4535,11 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem-aws-s3-v3/issues", - "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.2.0" + "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.3.0" }, "funding": [ { - "url": "https://offset.earth/frankdejonge", + "url": "https://ecologi.com/frankdejonge", "type": "custom" }, { @@ -4543,7 +4551,7 @@ "type": "tidelift" } ], - "time": "2022-07-26T07:22:40+00:00" + "time": "2022-09-09T10:03:42+00:00" }, { "name": "league/fractal", @@ -5577,20 +5585,20 @@ }, { "name": "nette/utils", - "version": "v3.2.7", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "0af4e3de4df9f1543534beab255ccf459e7a2c99" + "reference": "02a54c4c872b99e4ec05c4aec54b5a06eb0f6368" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/0af4e3de4df9f1543534beab255ccf459e7a2c99", - "reference": "0af4e3de4df9f1543534beab255ccf459e7a2c99", + "url": "https://api.github.com/repos/nette/utils/zipball/02a54c4c872b99e4ec05c4aec54b5a06eb0f6368", + "reference": "02a54c4c872b99e4ec05c4aec54b5a06eb0f6368", "shasum": "" }, "require": { - "php": ">=7.2 <8.2" + "php": ">=7.2 <8.3" }, "conflict": { "nette/di": "<3.0.6" @@ -5656,9 +5664,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v3.2.7" + "source": "https://github.com/nette/utils/tree/v3.2.8" }, - "time": "2022-01-24T11:29:14+00:00" + "time": "2022-09-12T23:36:20+00:00" }, { "name": "nikic/php-parser", @@ -7652,20 +7660,20 @@ }, { "name": "ramsey/uuid", - "version": "4.4.0", + "version": "4.5.0", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "373f7bacfcf3de038778ff27dcce5672ddbf4c8a" + "reference": "ef842484ba57f163c6d465ab744bfecb872a11d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/373f7bacfcf3de038778ff27dcce5672ddbf4c8a", - "reference": "373f7bacfcf3de038778ff27dcce5672ddbf4c8a", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/ef842484ba57f163c6d465ab744bfecb872a11d4", + "reference": "ef842484ba57f163c6d465ab744bfecb872a11d4", "shasum": "" }, "require": { - "brick/math": "^0.8 || ^0.9 || ^0.10", + "brick/math": "^0.8.8 || ^0.9 || ^0.10", "ext-ctype": "*", "ext-json": "*", "php": "^8.0", @@ -7686,12 +7694,13 @@ "php-mock/php-mock-mockery": "^1.3", "php-parallel-lint/php-parallel-lint": "^1.1", "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-mockery": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", "phpunit/phpunit": "^8.5 || ^9", - "slevomat/coding-standard": "^7.0", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^4.9" }, @@ -7729,7 +7738,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.4.0" + "source": "https://github.com/ramsey/uuid/tree/4.5.0" }, "funding": [ { @@ -7741,7 +7750,7 @@ "type": "tidelift" } ], - "time": "2022-08-05T17:58:37+00:00" + "time": "2022-09-15T01:44:53+00:00" }, { "name": "razorpay/razorpay", @@ -11935,16 +11944,16 @@ }, { "name": "tijsverkoyen/css-to-inline-styles", - "version": "2.2.4", + "version": "2.2.5", "source": { "type": "git", "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", - "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c" + "reference": "4348a3a06651827a27d989ad1d13efec6bb49b19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/da444caae6aca7a19c0c140f68c6182e337d5b1c", - "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/4348a3a06651827a27d989ad1d13efec6bb49b19", + "reference": "4348a3a06651827a27d989ad1d13efec6bb49b19", "shasum": "" }, "require": { @@ -11982,22 +11991,22 @@ "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", "support": { "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", - "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.4" + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.5" }, - "time": "2021-12-08T09:12:39+00:00" + "time": "2022-09-12T13:28:28+00:00" }, { "name": "turbo124/beacon", - "version": "v1.3.2", + "version": "v1.3.4", "source": { "type": "git", "url": "https://github.com/turbo124/beacon.git", - "reference": "e46e6122e28c2a7628ad40975bfd11a3ab883575" + "reference": "4a0c9c6af3d88142e89184e67e9f0547078d5ef0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/turbo124/beacon/zipball/e46e6122e28c2a7628ad40975bfd11a3ab883575", - "reference": "e46e6122e28c2a7628ad40975bfd11a3ab883575", + "url": "https://api.github.com/repos/turbo124/beacon/zipball/4a0c9c6af3d88142e89184e67e9f0547078d5ef0", + "reference": "4a0c9c6af3d88142e89184e67e9f0547078d5ef0", "shasum": "" }, "require": { @@ -12044,9 +12053,9 @@ "turbo124" ], "support": { - "source": "https://github.com/turbo124/beacon/tree/v1.3.2" + "source": "https://github.com/turbo124/beacon/tree/v1.3.4" }, - "time": "2022-09-08T08:08:59+00:00" + "time": "2022-09-09T23:30:23+00:00" }, { "name": "twilio/sdk", @@ -12741,16 +12750,16 @@ }, { "name": "brianium/paratest", - "version": "v6.6.3", + "version": "v6.6.4", "source": { "type": "git", "url": "https://github.com/paratestphp/paratest.git", - "reference": "f2d781bb9136cda2f5e73ee778049e80ba681cf6" + "reference": "4ce800dc32fd0292a4f05c00f347142dce1ecdda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/f2d781bb9136cda2f5e73ee778049e80ba681cf6", - "reference": "f2d781bb9136cda2f5e73ee778049e80ba681cf6", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/4ce800dc32fd0292a4f05c00f347142dce1ecdda", + "reference": "4ce800dc32fd0292a4f05c00f347142dce1ecdda", "shasum": "" }, "require": { @@ -12760,24 +12769,23 @@ "ext-simplexml": "*", "jean85/pretty-package-versions": "^2.0.5", "php": "^7.3 || ^8.0", - "phpunit/php-code-coverage": "^9.2.16", + "phpunit/php-code-coverage": "^9.2.17", "phpunit/php-file-iterator": "^3.0.6", "phpunit/php-timer": "^5.0.3", - "phpunit/phpunit": "^9.5.23", + "phpunit/phpunit": "^9.5.24", "sebastian/environment": "^5.1.4", - "symfony/console": "^5.4.9 || ^6.1.2", - "symfony/polyfill-php80": "^v1.26.0", - "symfony/process": "^5.4.8 || ^6.1.0" + "symfony/console": "^5.4.12 || ^6.1.4", + "symfony/process": "^5.4.11 || ^6.1.3" }, "require-dev": { - "doctrine/coding-standard": "^9.0.0", + "doctrine/coding-standard": "^10.0.0", "ext-pcov": "*", "ext-posix": "*", - "infection/infection": "^0.26.13", + "infection/infection": "^0.26.14", "malukenho/mcbumpface": "^1.1.5", "squizlabs/php_codesniffer": "^3.7.1", - "symfony/filesystem": "^5.4.9 || ^6.1.0", - "vimeo/psalm": "^4.26.0" + "symfony/filesystem": "^5.4.12 || ^6.1.4", + "vimeo/psalm": "^4.27.0" }, "bin": [ "bin/paratest", @@ -12818,7 +12826,7 @@ ], "support": { "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v6.6.3" + "source": "https://github.com/paratestphp/paratest/tree/v6.6.4" }, "funding": [ { @@ -12830,7 +12838,7 @@ "type": "paypal" } ], - "time": "2022-08-25T05:44:14+00:00" + "time": "2022-09-13T10:47:01+00:00" }, { "name": "composer/package-versions-deprecated", @@ -14988,16 +14996,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.6", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", "shasum": "" }, "require": { @@ -15050,7 +15058,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" }, "funding": [ { @@ -15058,7 +15066,7 @@ "type": "github" } ], - "time": "2020-10-26T15:49:45+00:00" + "time": "2022-09-14T12:41:17+00:00" }, { "name": "sebastian/complexity", @@ -15248,16 +15256,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", "shasum": "" }, "require": { @@ -15313,7 +15321,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" }, "funding": [ { @@ -15321,7 +15329,7 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2022-09-14T06:03:37+00:00" }, { "name": "sebastian/global-state", @@ -15676,16 +15684,16 @@ }, { "name": "sebastian/type", - "version": "3.1.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb44e1cc6e557418387ad815780360057e40753e" + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb44e1cc6e557418387ad815780360057e40753e", - "reference": "fb44e1cc6e557418387ad815780360057e40753e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", "shasum": "" }, "require": { @@ -15697,7 +15705,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -15720,7 +15728,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.1.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" }, "funding": [ { @@ -15728,7 +15736,7 @@ "type": "github" } ], - "time": "2022-08-29T06:55:37+00:00" + "time": "2022-09-12T14:47:03+00:00" }, { "name": "sebastian/version", diff --git a/config/ninja.php b/config/ninja.php index 5289374b4f34..b56ba5adf83d 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -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.21', - 'app_tag' => '5.5.21', + 'app_version' => '5.5.22', + 'app_tag' => '5.5.22', 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', ''), diff --git a/config/purchase.php b/config/purchase.php index 38a6c52dd3fa..2791bd868288 100644 --- a/config/purchase.php +++ b/config/purchase.php @@ -1,5 +1,6 @@ [], DidFailToRenew::class => [], DidRecover::class => [], - DidRenew::class => [], + DidRenew::class => [AppStoreRenewSubscription::class], InitialBuy::class => [], InteractiveRenewal::class => [], PriceIncreaseConsent::class => [], diff --git a/resources/views/portal/ninja2020/layout/payments.blade.php b/resources/views/portal/ninja2020/layout/payments.blade.php index b21a08abc7cf..9101bff6c5b5 100644 --- a/resources/views/portal/ninja2020/layout/payments.blade.php +++ b/resources/views/portal/ninja2020/layout/payments.blade.php @@ -11,7 +11,7 @@ @endpush @section('body') - @livewire('required-client-info', ['fields' => method_exists($gateway, 'getClientRequiredFields') ? $gateway->getClientRequiredFields() : [], 'contact' => auth()->guard('contact')->user(), 'countries' => $countries, 'company' => $company]) + @livewire('required-client-info', ['fields' => method_exists($gateway, 'getClientRequiredFields') ? $gateway->getClientRequiredFields() : [], 'contact' => auth()->guard('contact')->user(), 'countries' => $countries, 'company' => $company, 'company_gateway_id' => $gateway->company_gateway->id])
diff --git a/tests/Feature/CompanyGatewayApiTest.php b/tests/Feature/CompanyGatewayApiTest.php index 5b6bbf9e4b2f..b036dd35c8b9 100644 --- a/tests/Feature/CompanyGatewayApiTest.php +++ b/tests/Feature/CompanyGatewayApiTest.php @@ -512,6 +512,6 @@ class CompanyGatewayApiTest extends TestCase $company_gateway = CompanyGateway::find($id); - $this->assertEquals(1.2, $company_gateway->calcGatewayFee(10, GatewayType::CREDIT_CARD, true)); + $this->assertEquals(1.2, round($company_gateway->calcGatewayFee(10, GatewayType::CREDIT_CARD, true),1)); } } diff --git a/tests/Feature/CompanyGatewayResolutionTest.php b/tests/Feature/CompanyGatewayResolutionTest.php index 72f34e63b79c..ef294c2b26fc 100644 --- a/tests/Feature/CompanyGatewayResolutionTest.php +++ b/tests/Feature/CompanyGatewayResolutionTest.php @@ -233,6 +233,6 @@ class CompanyGatewayResolutionTest extends TestCase $this->cg->save(); $fee = $this->cg->calcGatewayFee(89, GatewayType::CREDIT_CARD, false); - $this->assertEquals(1.89, $fee); + $this->assertEquals(1.89, round($fee,2)); } }