Merge branch 'v5-develop' of https://github.com/turbo124/invoiceninja into v5-develop

This commit is contained in:
David Bomba 2024-08-01 12:19:08 +10:00
commit dcb44314b8
12 changed files with 88 additions and 69 deletions

View File

@ -1,5 +1,5 @@
<p align="center"> <p align="center">
<img src="https://raw.githubusercontent.com/hillelcoren/invoice-ninja/master/public/images/round_logo.png" alt="Sublime's custom image"/> <a href ="https://www.youtube.com/watch?v=CxGxXiotv0I" target="_blank" title="Invoice Ninja Overview Video"><img src="https://raw.githubusercontent.com/hillelcoren/invoice-ninja/master/public/images/round_logo.png" alt="Sublime's custom image"/></a>
</p> </p>
![v5-develop phpunit](https://github.com/invoiceninja/invoiceninja/workflows/phpunit/badge.svg?branch=v5-develop) ![v5-develop phpunit](https://github.com/invoiceninja/invoiceninja/workflows/phpunit/badge.svg?branch=v5-develop)
@ -8,25 +8,30 @@
# Invoice Ninja 5 # Invoice Ninja 5
## [Hosted](https://www.invoiceninja.com) | [Self-Hosted](https://www.invoiceninja.org) Invoice Ninja Version 5 is here! We've taken the best parts of version 4 and added the most requested features to create an invoicing application like no other. Check the [Invoice Ninja YouTube Channel](https://www.youtube.com/@appinvoiceninja) to get up to speed, or try the [Demo](https://react.invoicing.co/demo) now.
Join us on [Slack](http://slack.invoiceninja.com), [Discord](https://discord.gg/ZwEdtfCwXA), [Support Forum](https://forum.invoiceninja.com) **Choose your setup**
## Introduction - [Hosted](https://www.invoiceninja.com): Our hosted version is a Software as a Service (SaaS) solution. You're up and running in under 5 minutes, with no need to worry about hosting or server infrastructure.
- [Self-Hosted](https://www.invoiceninja.org): For those who prefer to manage their own hosting and server infrastructure. This version gives you full control and flexibility.
Version 5 of Invoice Ninja is here! All Pro and Enterprise features from the hosted app are included in the open-source code. We offer a $30 per year white-label license to remove the Invoice Ninja branding from client-facing parts of the app.
We took the best parts of version 4 and add the most requested features
to produce a invoicing application like no other.
All Pro and Enterprise features from the hosted app are included in the open code. #### Get social with us
We offer a $30 per year white-label license to remove the Invoice Ninja branding from client facing parts of the app.
* [Videos](https://www.youtube.com/@appinvoiceninja)
* [API Documentation](https://api-docs.invoicing.co/)
* [APP Documentation](https://invoiceninja.github.io/)
* [Support Forum](https://forum.invoiceninja.com) * [Support Forum](https://forum.invoiceninja.com)
* [Slack](http://slack.invoiceninja.com)
* [Discord](https://discord.gg/ZwEdtfCwXA)
* [Instagram](https://www.instagram.com/appinvoiceninja)
## Setup #### Documentation
* [Invoice Ninja - API](https://api-docs.invoicing.co/)
* [Invoice Ninja - Developer Guide](https://invoiceninja.github.io/en/developer-guide/)
* [Invoice Ninja - User Guide](https://invoiceninja.github.io/en/user-guide/)
* [Invoice Ninja - Self-Hosted Installation Guide](https://invoiceninja.github.io/en/self-host-installation/)
## Installation Options and Clients
### Mobile Apps ### Mobile Apps
* [iPhone](https://apps.apple.com/app/id1503970375?platform=iphone) * [iPhone](https://apps.apple.com/app/id1503970375?platform=iphone)
@ -39,16 +44,21 @@ We offer a $30 per year white-label license to remove the Invoice Ninja branding
* [Linux - Snap](https://snapcraft.io/invoiceninja) * [Linux - Snap](https://snapcraft.io/invoiceninja)
* [Linux - Flatpak](https://flathub.org/apps/com.invoiceninja.InvoiceNinja) * [Linux - Flatpak](https://flathub.org/apps/com.invoiceninja.InvoiceNinja)
### Installation Options ### Self-Hosted Server Installation
**Note:** The self-hosted options do support the desktop and mobile apps.
* [Server or VM](https://invoiceninja.github.io/en/self-host-installation/)
* [Docker File](https://hub.docker.com/r/invoiceninja/invoiceninja/) * [Docker File](https://hub.docker.com/r/invoiceninja/invoiceninja/)
* [Cloudron](https://cloudron.io/store/com.invoiceninja.cloudronapp.html) * [Cloudron](https://www.cloudron.io/store/com.invoiceninja.cloudronapp2.html)
* [Softaculous](https://www.softaculous.com/apps/ecommerce/Invoice_Ninja) * [Softaculous](https://www.softaculous.com/apps/ecommerce/Invoice_Ninja)
### Recommended Providers ### Recommended Providers
* [Stripe](https://stripe.com/) * [Stripe](https://stripe.com/)
* [Postmark](https://postmarkapp.com/) * [Postmark](https://postmarkapp.com/)
## Quick Hosting Setup ## [Advanced] Quick Hosting Setup
In addition to the official [Invoice Ninja - Self-Hosted Installation Guide](https://invoiceninja.github.io/en/self-host-installation/) we have a few commands for you.
```sh ```sh
git clone --single-branch --branch v5-stable https://github.com/invoiceninja/invoiceninja.git git clone --single-branch --branch v5-stable https://github.com/invoiceninja/invoiceninja.git
@ -84,6 +94,7 @@ pass: password
``` ```
## Developers Guide ## Developers Guide
In addition to the official [Invoice Ninja - Developer Guide](https://invoiceninja.github.io/en/developer-guide/) we've got your back with some insights.
### App Design ### App Design

View File

@ -1258,7 +1258,7 @@ class BaseExport
$date_range = $this->input['date_range']; $date_range = $this->input['date_range'];
if (array_key_exists('date_key', $this->input) && strlen($this->input['date_key']) > 1 && ($table_name && $this->columnExists($table_name, $this->input['date_key']))) { if (array_key_exists('date_key', $this->input) && strlen($this->input['date_key'] ?? '') > 1 && ($table_name && $this->columnExists($table_name, $this->input['date_key']))) {
$this->date_key = $this->input['date_key']; $this->date_key = $this->input['date_key'];
} }

View File

@ -29,7 +29,7 @@ class TaskExport extends BaseExport
{ {
private $entity_transformer; private $entity_transformer;
public string $date_key = 'created_at'; public string $date_key = 'calculated_start_date';
private string $date_format = 'Y-m-d'; private string $date_format = 'Y-m-d';

View File

@ -155,11 +155,13 @@ class BankTransactionFilters extends QueryFilters
$dir = ($sort_col[1] == 'asc') ? 'asc' : 'desc'; $dir = ($sort_col[1] == 'asc') ? 'asc' : 'desc';
if ($sort_col[0] == 'deposit') { if ($sort_col[0] == 'deposit') {
return $this->builder->where('base_type', 'CREDIT')->orderBy('amount', $dir); return $this->builder->orderByRaw("(CASE WHEN base_type = 'CREDIT' THEN amount END) $dir")->orderBy('amount', $dir);
// return $this->builder->where('base_type', 'CREDIT')->orderBy('amount', $dir);
} }
if ($sort_col[0] == 'withdrawal') { if ($sort_col[0] == 'withdrawal') {
return $this->builder->where('base_type', 'DEBIT')->orderBy('amount', $dir); return $this->builder->orderByRaw("(CASE WHEN base_type = 'DEBIT' THEN amount END) $dir")->orderBy('amount', $dir);
// return $this->builder->where('base_type', 'DEBIT')->orderBy('amount', $dir);
} }
if ($sort_col[0] == 'status') { if ($sort_col[0] == 'status') {

View File

@ -11,16 +11,18 @@
namespace App\Helpers\Invoice; namespace App\Helpers\Invoice;
use App\DataMapper\BaseSettings; use App\Models\Quote;
use App\DataMapper\InvoiceItem; use App\Utils\Number;
use App\DataMapper\Tax\RuleInterface;
use App\Models\Client; use App\Models\Client;
use App\Models\Credit; use App\Models\Credit;
use App\Models\Vendor;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\PurchaseOrder; use App\Models\PurchaseOrder;
use App\Models\Quote;
use App\Models\RecurringInvoice;
use App\Models\RecurringQuote; use App\Models\RecurringQuote;
use App\DataMapper\InvoiceItem;
use App\DataMapper\BaseSettings;
use App\Models\RecurringInvoice;
use App\DataMapper\Tax\RuleInterface;
use App\Utils\Traits\NumberFormatter; use App\Utils\Traits\NumberFormatter;
class InvoiceItemSum class InvoiceItemSum
@ -120,7 +122,7 @@ class InvoiceItemSum
private $tax_collection; private $tax_collection;
private ?Client $client; private Client | Vendor $client;
private bool $calc_tax = false; private bool $calc_tax = false;
@ -131,10 +133,10 @@ class InvoiceItemSum
$this->tax_collection = collect([]); $this->tax_collection = collect([]);
$this->invoice = $invoice; $this->invoice = $invoice;
$this->client = $invoice->client ?? $invoice->vendor;
if ($this->invoice->client) { if ($this->invoice->client) {
$this->currency = $this->invoice->client->currency(); $this->currency = $this->invoice->client->currency();
$this->client = $this->invoice->client;
$this->shouldCalculateTax(); $this->shouldCalculateTax();
} else { } else {
$this->currency = $this->invoice->vendor->currency(); $this->currency = $this->invoice->vendor->currency();
@ -313,7 +315,7 @@ class InvoiceItemSum
$key = str_replace(' ', '', $tax_name.$tax_rate); $key = str_replace(' ', '', $tax_name.$tax_rate);
$group_tax = ['key' => $key, 'total' => $tax_total, 'tax_name' => $tax_name.' '.floatval($tax_rate).'%']; $group_tax = ['key' => $key, 'total' => $tax_total, 'tax_name' => $tax_name.' '.Number::formatValueNoTrailingZeroes(floatval($tax_rate), $this->client).'%'];
$this->tax_collection->push(collect($group_tax)); $this->tax_collection->push(collect($group_tax));
} }

View File

@ -11,14 +11,16 @@
namespace App\Helpers\Invoice; namespace App\Helpers\Invoice;
use App\DataMapper\Tax\RuleInterface; use App\Models\Quote;
use App\Utils\Number;
use App\Models\Client; use App\Models\Client;
use App\Models\Credit; use App\Models\Credit;
use App\Models\Vendor;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\PurchaseOrder; use App\Models\PurchaseOrder;
use App\Models\Quote;
use App\Models\RecurringInvoice;
use App\Models\RecurringQuote; use App\Models\RecurringQuote;
use App\Models\RecurringInvoice;
use App\DataMapper\Tax\RuleInterface;
use App\Utils\Traits\NumberFormatter; use App\Utils\Traits\NumberFormatter;
class InvoiceItemSumInclusive class InvoiceItemSumInclusive
@ -109,7 +111,7 @@ class InvoiceItemSumInclusive
private bool $calc_tax = false; private bool $calc_tax = false;
private ?Client $client; private Client | Vendor $client;
private RuleInterface $rule; private RuleInterface $rule;
@ -118,10 +120,10 @@ class InvoiceItemSumInclusive
$this->tax_collection = collect([]); $this->tax_collection = collect([]);
$this->invoice = $invoice; $this->invoice = $invoice;
$this->client = $invoice->client ?? $invoice->vendor;
if ($this->invoice->client) { if ($this->invoice->client) {
$this->currency = $this->invoice->client->currency(); $this->currency = $this->invoice->client->currency();
$this->client = $this->invoice->client;
$this->shouldCalculateTax(); $this->shouldCalculateTax();
} else { } else {
$this->currency = $this->invoice->vendor->currency(); $this->currency = $this->invoice->vendor->currency();
@ -265,7 +267,7 @@ class InvoiceItemSumInclusive
$key = str_replace(' ', '', $tax_name.$tax_rate); $key = str_replace(' ', '', $tax_name.$tax_rate);
$group_tax = ['key' => $key, 'total' => $tax_total, 'tax_name' => $tax_name.' '.$tax_rate.'%']; $group_tax = ['key' => $key, 'total' => $tax_total, 'tax_name' => $tax_name.' '.Number::formatValueNoTrailingZeroes(floatval($tax_rate), $this->client).'%'];
$this->tax_collection->push(collect($group_tax)); $this->tax_collection->push(collect($group_tax));
} }

View File

@ -11,12 +11,14 @@
namespace App\Helpers\Invoice; namespace App\Helpers\Invoice;
use App\Models\Client;
use App\Models\Credit; use App\Models\Credit;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\PurchaseOrder; use App\Models\PurchaseOrder;
use App\Models\Quote; use App\Models\Quote;
use App\Models\RecurringInvoice; use App\Models\RecurringInvoice;
use App\Models\RecurringQuote; use App\Models\RecurringQuote;
use App\Models\Vendor;
use App\Utils\Number; use App\Utils\Number;
use App\Utils\Traits\NumberFormatter; use App\Utils\Traits\NumberFormatter;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@ -50,6 +52,8 @@ class InvoiceSum
private $precision; private $precision;
private Client | Vendor $client;
public InvoiceItemSum $invoice_items; public InvoiceItemSum $invoice_items;
private $rappen_rounding = false; private $rappen_rounding = false;
@ -60,18 +64,15 @@ class InvoiceSum
*/ */
public function __construct($invoice) public function __construct($invoice)
{ {
$this->invoice = $invoice; $this->invoice = $invoice;
$this->client = $invoice->client ?? $invoice->vendor;
if ($this->invoice->client) { $this->precision = $this->client->currency()->precision;
$this->precision = $this->invoice->client->currency()->precision; $this->rappen_rounding = $this->client->getSetting('enable_rappen_rounding');
$this->rappen_rounding = $this->invoice->client->getSetting('enable_rappen_rounding');
} else {
$this->precision = $this->invoice->vendor->currency()->precision;
$this->rappen_rounding = $this->invoice->vendor->getSetting('enable_rappen_rounding');
}
$this->tax_map = new Collection(); $this->tax_map = new Collection();
} }
public function build() public function build()
@ -131,7 +132,7 @@ class InvoiceSum
$tax += $this->getSurchargeTaxTotalForKey($this->invoice->tax_name1, $this->invoice->tax_rate1); $tax += $this->getSurchargeTaxTotalForKey($this->invoice->tax_name1, $this->invoice->tax_rate1);
$this->total_taxes += $tax; $this->total_taxes += $tax;
$this->total_tax_map[] = ['name' => $this->invoice->tax_name1.' '.floatval($this->invoice->tax_rate1).'%', 'total' => $tax]; $this->total_tax_map[] = ['name' => $this->invoice->tax_name1.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate1), $this->client).'%', 'total' => $tax];
} }
if (is_string($this->invoice->tax_name2) && strlen($this->invoice->tax_name2) >= 2) { if (is_string($this->invoice->tax_name2) && strlen($this->invoice->tax_name2) >= 2) {
@ -139,7 +140,7 @@ class InvoiceSum
$tax += $this->getSurchargeTaxTotalForKey($this->invoice->tax_name2, $this->invoice->tax_rate2); $tax += $this->getSurchargeTaxTotalForKey($this->invoice->tax_name2, $this->invoice->tax_rate2);
$this->total_taxes += $tax; $this->total_taxes += $tax;
$this->total_tax_map[] = ['name' => $this->invoice->tax_name2.' '.floatval($this->invoice->tax_rate2).'%', 'total' => $tax]; $this->total_tax_map[] = ['name' => $this->invoice->tax_name2.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate2), $this->client).'%', 'total' => $tax];
} }
if (is_string($this->invoice->tax_name3) && strlen($this->invoice->tax_name3) >= 2) { if (is_string($this->invoice->tax_name3) && strlen($this->invoice->tax_name3) >= 2) {
@ -147,7 +148,7 @@ class InvoiceSum
$tax += $this->getSurchargeTaxTotalForKey($this->invoice->tax_name3, $this->invoice->tax_rate3); $tax += $this->getSurchargeTaxTotalForKey($this->invoice->tax_name3, $this->invoice->tax_rate3);
$this->total_taxes += $tax; $this->total_taxes += $tax;
$this->total_tax_map[] = ['name' => $this->invoice->tax_name3.' '.floatval($this->invoice->tax_rate3).'%', 'total' => $tax]; $this->total_tax_map[] = ['name' => $this->invoice->tax_name3.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate3), $this->client).'%', 'total' => $tax];
} }
return $this; return $this;

View File

@ -12,7 +12,10 @@
namespace App\Helpers\Invoice; namespace App\Helpers\Invoice;
use App\Models\Quote; use App\Models\Quote;
use App\Utils\Number;
use App\Models\Client;
use App\Models\Credit; use App\Models\Credit;
use App\Models\Vendor;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\PurchaseOrder; use App\Models\PurchaseOrder;
use App\Models\RecurringQuote; use App\Models\RecurringQuote;
@ -49,6 +52,8 @@ class InvoiceSumInclusive
private $rappen_rounding = false; private $rappen_rounding = false;
private Client | Vendor $client;
public InvoiceItemSumInclusive $invoice_items; public InvoiceItemSumInclusive $invoice_items;
/** /**
* Constructs the object with Invoice and Settings object. * Constructs the object with Invoice and Settings object.
@ -58,14 +63,10 @@ class InvoiceSumInclusive
public function __construct($invoice) public function __construct($invoice)
{ {
$this->invoice = $invoice; $this->invoice = $invoice;
$this->client = $invoice->client ?? $invoice->vendor;
if ($this->invoice->client) { $this->precision = $this->client->currency()->precision;
$this->precision = $this->invoice->client->currency()->precision; $this->rappen_rounding = $this->client->getSetting('enable_rappen_rounding');
$this->rappen_rounding = $this->invoice->client->getSetting('enable_rappen_rounding');
} else {
$this->precision = $this->invoice->vendor->currency()->precision;
$this->rappen_rounding = $this->invoice->vendor->getSetting('enable_rappen_rounding');
}
$this->tax_map = new Collection(); $this->tax_map = new Collection();
} }
@ -157,19 +158,19 @@ class InvoiceSumInclusive
$tax = $this->calcInclusiveLineTax($this->invoice->tax_rate1, $amount); $tax = $this->calcInclusiveLineTax($this->invoice->tax_rate1, $amount);
$this->total_taxes += $tax; $this->total_taxes += $tax;
$this->total_tax_map[] = ['name' => $this->invoice->tax_name1.' '.floatval($this->invoice->tax_rate1).'%', 'total' => $tax]; $this->total_tax_map[] = ['name' => $this->invoice->tax_name1.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate1), $this->client).'%', 'total' => $tax];
} }
if (is_string($this->invoice->tax_name2) && strlen($this->invoice->tax_name2) > 1) { if (is_string($this->invoice->tax_name2) && strlen($this->invoice->tax_name2) > 1) {
$tax = $this->calcInclusiveLineTax($this->invoice->tax_rate2, $amount); $tax = $this->calcInclusiveLineTax($this->invoice->tax_rate2, $amount);
$this->total_taxes += $tax; $this->total_taxes += $tax;
$this->total_tax_map[] = ['name' => $this->invoice->tax_name2.' '.floatval($this->invoice->tax_rate2).'%', 'total' => $tax]; $this->total_tax_map[] = ['name' => $this->invoice->tax_name2.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate2), $this->client).'%', 'total' => $tax];
} }
if (is_string($this->invoice->tax_name3) && strlen($this->invoice->tax_name3) > 1) { if (is_string($this->invoice->tax_name3) && strlen($this->invoice->tax_name3) > 1) {
$tax = $this->calcInclusiveLineTax($this->invoice->tax_rate3, $amount); $tax = $this->calcInclusiveLineTax($this->invoice->tax_rate3, $amount);
$this->total_taxes += $tax; $this->total_taxes += $tax;
$this->total_tax_map[] = ['name' => $this->invoice->tax_name3.' '.floatval($this->invoice->tax_rate3).'%', 'total' => $tax]; $this->total_tax_map[] = ['name' => $this->invoice->tax_name3.' '.Number::formatValueNoTrailingZeroes(floatval($this->invoice->tax_rate3), $this->client).'%', 'total' => $tax];
} }
return $this; return $this;

View File

@ -153,7 +153,7 @@ class BrowserPay implements MethodInterface
$this->stripe->client->company, $this->stripe->client->company,
); );
return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id)]); return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]);
} }
/** /**

View File

@ -160,7 +160,7 @@ class CreditCard
} }
} }
return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id)]); return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]);
} }
public function processUnsuccessfulPayment($server_response) public function processUnsuccessfulPayment($server_response)

View File

@ -739,7 +739,7 @@ class PdfBuilder
if ($item->is_amount_discount) { if ($item->is_amount_discount) {
$data[$key][$table_type.'.discount'] = $this->service->config->formatMoney($item->discount); $data[$key][$table_type.'.discount'] = $this->service->config->formatMoney($item->discount);
} else { } else {
$data[$key][$table_type.'.discount'] = floatval($item->discount).'%'; $data[$key][$table_type.'.discount'] = $this->service->config->formatValueNoTrailingZeroes(floatval($item->discount)).'%';
} }
} else { } else {
$data[$key][$table_type.'.discount'] = ''; $data[$key][$table_type.'.discount'] = '';
@ -749,17 +749,17 @@ class PdfBuilder
// but that's no longer necessary. // but that's no longer necessary.
if (isset($item->tax_rate1)) { if (isset($item->tax_rate1)) {
$data[$key][$table_type.'.tax_rate1'] = floatval($item->tax_rate1).'%'; $data[$key][$table_type.'.tax_rate1'] = $this->service->config->formatValueNoTrailingZeroes(floatval($item->tax_rate1)).'%';
$data[$key][$table_type.'.tax1'] = &$data[$key][$table_type.'.tax_rate1']; $data[$key][$table_type.'.tax1'] = &$data[$key][$table_type.'.tax_rate1'];
} }
if (isset($item->tax_rate2)) { if (isset($item->tax_rate2)) {
$data[$key][$table_type.'.tax_rate2'] = floatval($item->tax_rate2).'%'; $data[$key][$table_type.'.tax_rate2'] = $this->service->config->formatValueNoTrailingZeroes(floatval($item->tax_rate2)).'%';
$data[$key][$table_type.'.tax2'] = &$data[$key][$table_type.'.tax_rate2']; $data[$key][$table_type.'.tax2'] = &$data[$key][$table_type.'.tax_rate2'];
} }
if (isset($item->tax_rate3)) { if (isset($item->tax_rate3)) {
$data[$key][$table_type.'.tax_rate3'] = floatval($item->tax_rate3).'%'; $data[$key][$table_type.'.tax_rate3'] = $this->service->config->formatValueNoTrailingZeroes(floatval($item->tax_rate3)).'%';
$data[$key][$table_type.'.tax3'] = &$data[$key][$table_type.'.tax_rate3']; $data[$key][$table_type.'.tax3'] = &$data[$key][$table_type.'.tax_rate3'];
} }

12
composer.lock generated
View File

@ -16199,16 +16199,16 @@
}, },
{ {
"name": "friendsofphp/php-cs-fixer", "name": "friendsofphp/php-cs-fixer",
"version": "v3.60.0", "version": "v3.61.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "e595e4e070d17c5d42ed8c4206f630fcc5f401a4" "reference": "94a87189f55814e6cabca2d9a33b06de384a2ab8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/e595e4e070d17c5d42ed8c4206f630fcc5f401a4", "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/94a87189f55814e6cabca2d9a33b06de384a2ab8",
"reference": "e595e4e070d17c5d42ed8c4206f630fcc5f401a4", "reference": "94a87189f55814e6cabca2d9a33b06de384a2ab8",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -16290,7 +16290,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.60.0" "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.61.1"
}, },
"funding": [ "funding": [
{ {
@ -16298,7 +16298,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-07-25T09:26:51+00:00" "time": "2024-07-31T14:33:15+00:00"
}, },
{ {
"name": "hamcrest/hamcrest-php", "name": "hamcrest/hamcrest-php",