diff --git a/VERSION.txt b/VERSION.txt index 86c5a84a4d..13ee93ba38 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.12.48 \ No newline at end of file +5.12.49 \ No newline at end of file diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 4fca7fdfe6..442e123e6c 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -200,6 +200,40 @@ class LoginController extends BaseController } } + public function refreshReact(Request $request) + { + $truth = app()->make(TruthSource::class); + + if ($truth->getCompanyToken()) { + $company_token = $truth->getCompanyToken(); + } else { + $company_token = CompanyToken::where('token', $request->header('X-API-TOKEN'))->first(); + } + + $cu = CompanyUser::query() + ->where('user_id', $company_token->user_id); + + if ($cu->count() == 0) { + return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400); + } + + $cu->first()->account->companies->each(function ($company) use ($cu, $request) { + if ($company->tokens()->where('is_system', true)->count() == 0) { + (new CreateCompanyToken($company, $cu->first()->user, $request->server('HTTP_USER_AGENT')))->handle(); + } + }); + + if ($request->has('current_company') && $request->input('current_company') == 'true') { + $cu->where('company_id', $company_token->company_id); + } + + if (Ninja::isHosted() && !$cu->first()->is_owner && !$cu->first()->user->account->isEnterprisePaidClient()) { + return response()->json(['message' => 'Pro / Free accounts only the owner can log in. Please upgrade'], 403); + } + + return $this->refreshReactResponse($cu); + } + /** * Refreshes the data feed with the current Company User. * diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index 3f71ca67fe..0cf9c3cf77 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -297,6 +297,44 @@ class BaseController extends Controller return response()->make($error, $httpErrorCode, $headers); } + /** + * Heavily reduced refresh query to reduce DB burden + * + * @param Builder $query + * @return Response| \Illuminate\Http\JsonResponse + */ + protected function refreshReactResponse($query) + { + $this->manager->parseIncludes([ + 'account', + 'user.company_user', + 'token', + 'company.tax_rates', + ]); + + $this->serializer = request()->input('serializer') ?: EntityTransformer::API_SERIALIZER_ARRAY; + + if ($this->serializer === EntityTransformer::API_SERIALIZER_JSON) { + $this->manager->setSerializer(new JsonApiSerializer()); + } else { + $this->manager->setSerializer(new ArraySerializer()); + } + + $transformer = new $this->entity_transformer($this->serializer); + + $limit = $this->resolveQueryLimit(); + + $paginator = $query->paginate($limit); + + /** @phpstan-ignore-next-line */ + $query = $paginator->getCollection(); // @phpstan-ignore-line + + $resource = new Collection($query, $transformer, $this->entity_type); + + $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); + + return $this->response($this->manager->createData($resource)->toArray()); + } /** * Refresh API response with latest cahnges * @@ -681,7 +719,10 @@ class BaseController extends Controller // Set created_at to current time to filter out all existing related records // (designs, documents, groups, etc.) for a minimal response payload request()->merge(['created_at' => time()]); - return $this->miniLoadResponse($query); + + //2026-01-23: Improve Login Performance for react. + return $this->refreshReactResponse($query); + // return $this->miniLoadResponse($query); } elseif ($user->getCompany()->is_large) { $this->manager->parseIncludes($this->mini_load); diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 6277825cae..25a069e96c 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -607,7 +607,7 @@ class ProjectController extends BaseController $this->entity_transformer = InvoiceTransformer::class; $this->entity_type = Invoice::class; - $invoice = $this->project_repo->invoice($project); + $invoice = $this->project_repo->invoice(collect([$project])); return $this->itemResponse($invoice); } diff --git a/app/Jobs/Cron/InvoiceTaxSummary.php b/app/Jobs/Cron/InvoiceTaxSummary.php index e8eadf47de..58500424a4 100644 --- a/app/Jobs/Cron/InvoiceTaxSummary.php +++ b/app/Jobs/Cron/InvoiceTaxSummary.php @@ -44,6 +44,9 @@ class InvoiceTaxSummary implements ShouldQueue public function handle() { + nlog("InvoiceTaxSummary:: Starting job @ " . now()->toDateTimeString()); + $start = now(); + $currentUtcHour = now()->hour; $transitioningTimezones = $this->getTransitioningTimezones($currentUtcHour); @@ -56,6 +59,8 @@ class InvoiceTaxSummary implements ShouldQueue $this->processCompanyTaxSummary($company); } } + + nlog("InvoiceTaxSummary:: Job completed in " . now()->diffInSeconds($start) . " seconds"); } private function getTransitioningTimezones($utcHour) @@ -117,7 +122,11 @@ class InvoiceTaxSummary implements ShouldQueue } // Get companies that have timezone_id in their JSON settings matching the transitioning timezones - return Company::whereRaw("JSON_EXTRACT(settings, '$.timezone_id') IN (" . implode(',', $timezoneIds) . ")")->get(); + $companies = Company::whereRaw("JSON_EXTRACT(settings, '$.timezone_id') IN (" . implode(',', $timezoneIds) . ")")->get(); + + nlog("InvoiceTaxSummary:: Found " . $companies->count() . " companies in timezones: " . implode(',', $timezoneIds)); + + return $companies; } private function processCompanyTaxSummary($company) diff --git a/app/Jobs/Ninja/TaskScheduler.php b/app/Jobs/Ninja/TaskScheduler.php index 960b531978..37a9908d9e 100644 --- a/app/Jobs/Ninja/TaskScheduler.php +++ b/app/Jobs/Ninja/TaskScheduler.php @@ -64,7 +64,12 @@ class TaskScheduler implements ShouldQueue //@var \App\Models\Schedule $scheduler $scheduler->service()->runTask(); } catch (\Throwable $e) { + nlog("Exception:: TaskScheduler:: Doing job :: {$scheduler->id} :: {$scheduler->name}" . $e->getMessage()); + + if (app()->bound('sentry')) { + app('sentry')->captureException($e); + } } }); diff --git a/app/Mail/Admin/EntityFailedSendObject.php b/app/Mail/Admin/EntityFailedSendObject.php index 124263f3ab..cc06af31cc 100644 --- a/app/Mail/Admin/EntityFailedSendObject.php +++ b/app/Mail/Admin/EntityFailedSendObject.php @@ -46,6 +46,31 @@ class EntityFailedSendObject { $this->invitation = $invitation; $this->entity_type = $entity_type; + + // Load relationships if they're not already loaded (e.g., when withoutRelations() was called) + if (!$invitation->relationLoaded('contact')) { + $invitation->load('contact'); + } + if (!$invitation->relationLoaded('company')) { + $invitation->load('company.account'); + } else { + // If company is loaded, ensure account is also loaded + if ($invitation->company && !$invitation->company->relationLoaded('account')) { + $invitation->company->load('account'); + } + } + if (!$invitation->relationLoaded($entity_type)) { + $invitation->load([$entity_type => function ($query) { + $query->with('client'); + }]); + } else { + // If entity is loaded, ensure client is also loaded + $entity = $invitation->{$entity_type}; + if ($entity && !$entity->relationLoaded('client')) { + $entity->load('client'); + } + } + $this->entity = $invitation->{$entity_type}; $this->contact = $invitation->contact; $this->company = $invitation->company; diff --git a/app/Repositories/ProjectRepository.php b/app/Repositories/ProjectRepository.php index b11c65b5b5..fdc6fb459d 100644 --- a/app/Repositories/ProjectRepository.php +++ b/app/Repositories/ProjectRepository.php @@ -21,13 +21,23 @@ use App\Models\Project; * Class for project repository. */ class ProjectRepository extends BaseRepository -{ +{ + /** + * Invoices a collection of projects into a single invoice. + * + * @param mixed $projects + * @return App\Models\Invoice + */ public function invoice(mixed $projects) { $_project = $projects->first(); $invoice = InvoiceFactory::create($_project->company_id, $_project->user_id); $invoice->client_id = $_project->client_id; + + if(count($projects) == 1) { + $invoice->project_id = $_project->id; + } // $invoice->project_id = $project->id; $lines = []; diff --git a/app/Services/Client/ClientService.php b/app/Services/Client/ClientService.php index 7903205af7..5dbd159884 100644 --- a/app/Services/Client/ClientService.php +++ b/app/Services/Client/ClientService.php @@ -178,7 +178,7 @@ class ClientService $credits = Credit::withTrashed()->where('client_id', $this->client->id) ->where('is_deleted', false) ->where(function ($query) { - $query->whereDate('due_date', '<=', now()->format('Y-m-d')) + $query->where('due_date', '>=', now()->format('Y-m-d')) ->orWhereNull('due_date'); }) ->orderBy('created_at', 'ASC'); @@ -192,7 +192,7 @@ class ClientService ->where('is_deleted', false) ->where('balance', '>', 0) ->where(function ($query) { - $query->whereDate('due_date', '<=', now()->format('Y-m-d')) + $query->where('due_date', '>=', now()->format('Y-m-d')) ->orWhereNull('due_date'); }) ->orderBy('created_at', 'ASC')->get(); diff --git a/app/Services/EDocument/Standards/Peppol.php b/app/Services/EDocument/Standards/Peppol.php index 7197ff4ef2..1aaaf89730 100644 --- a/app/Services/EDocument/Standards/Peppol.php +++ b/app/Services/EDocument/Standards/Peppol.php @@ -1407,11 +1407,13 @@ class Peppol extends AbstractService $party->PartyIdentification[] = $pi; - $pts = new \InvoiceNinja\EInvoice\Models\Peppol\PartyTaxSchemeType\PartyTaxScheme(); + //// If this is intracommunity supply, ensure that the country prefix is on the party tax scheme + $pts = new \InvoiceNinja\EInvoice\Models\Peppol\PartyTaxSchemeType\PartyTaxScheme(); $companyID = new \InvoiceNinja\EInvoice\Models\Peppol\IdentifierType\CompanyID(); - $companyID->value = preg_replace("/[^a-zA-Z0-9]/", "", $this->invoice->client->vat_number); + $companyID->value = $this->ensureVatNumberPrefix($this->invoice->client->vat_number, $this->invoice->client->country->iso_3166_2); $pts->CompanyID = $companyID; + //// If this is intracommunity supply, ensure that the country prefix is on the party tax scheme $ts = new TaxScheme(); $id = new ID(); @@ -1512,8 +1514,13 @@ class Peppol extends AbstractService $location->Address = $address; $delivery->DeliveryLocation = $location; - if (isset($this->invoice->e_invoice->Invoice->Delivery[0]->ActualDeliveryDate->date)) { - $delivery->ActualDeliveryDate = new \DateTime($this->invoice->e_invoice->Invoice->Delivery[0]->ActualDeliveryDate->date); + // Safely extract delivery date using data_get to handle missing properties + $delivery_date = data_get($this->invoice->e_invoice, 'Invoice.Delivery.0.ActualDeliveryDate.date') + ?? data_get($this->invoice->e_invoice, 'Invoice.Delivery.0.ActualDeliveryDate') + ?? null; + + if ($delivery_date) { + $delivery->ActualDeliveryDate = new \DateTime($delivery_date); } return [$delivery]; @@ -1915,6 +1922,31 @@ class Peppol extends AbstractService return '0037'; } + /** + * Ensures the VAT number has the correct country code prefix. + * + * @param string $vatNumber The raw VAT number. + * @param string $countryCode The 2-letter ISO country code. + * @return string The formatted VAT number with prefix. + */ + private function ensureVatNumberPrefix(string $vatNumber, string $countryCode): string + { + // Handle Greece special case + $prefix = ($countryCode === 'GR') ? 'EL' : $countryCode; + + // Clean the VAT number by removing non-alphanumeric characters + $cleanedVat = preg_replace("/[^a-zA-Z0-9]/", "", $vatNumber); + + // Check if the VAT number already starts with the country prefix + // If it does, return it as-is (preserving any check digits like "AA" in "FRAA123456789") + if (str_starts_with(strtoupper($cleanedVat), strtoupper($prefix))) { + return $cleanedVat; + } + + // If the prefix is missing, clean and prepend it + return $prefix . $cleanedVat; + } + public function getErrors(): array { return $this->errors; diff --git a/app/Services/Scheduler/EmailReport.php b/app/Services/Scheduler/EmailReport.php index eded156c03..3aa60a3fc3 100644 --- a/app/Services/Scheduler/EmailReport.php +++ b/app/Services/Scheduler/EmailReport.php @@ -58,6 +58,10 @@ class EmailReport $start_end_dates = $this->calculateStartAndEndDates($this->scheduler->parameters, $this->scheduler->company); $data = $this->scheduler->parameters; + + if(!isset($data['user_id'])) { + $data['user_id'] = $this->scheduler->user_id; + } $data['start_date'] = $start_end_dates[0]; $data['end_date'] = $start_end_dates[1]; diff --git a/app/Services/Template/TemplateService.php b/app/Services/Template/TemplateService.php index 6391d59e7c..77772bd60d 100644 --- a/app/Services/Template/TemplateService.php +++ b/app/Services/Template/TemplateService.php @@ -161,7 +161,7 @@ class TemplateService $this->twig->addFilter($filter); $allowedTags = ['if', 'for', 'set', 'filter']; - $allowedFilters = ['default', 'groupBy','capitalize', 'abs', 'date_modify', 'keys', 'join', 'reduce', 'format_date','json_decode','date_modify','trim','round','format_spellout_number','split', 'reduce','replace', 'escape', 'e', 'reverse', 'shuffle', 'slice', 'batch', 'title', 'sort', 'split', 'upper', 'lower', 'capitalize', 'filter', 'length', 'merge','format_currency', 'format_number','format_percent_number','map', 'join', 'first', 'date', 'sum', 'number_format','nl2br','striptags','markdown_to_html']; + $allowedFilters = ['url_encode','default', 'groupBy','capitalize', 'abs', 'date_modify', 'keys', 'join', 'reduce', 'format_date','json_decode','date_modify','trim','round','format_spellout_number','split', 'reduce','replace', 'escape', 'e', 'reverse', 'shuffle', 'slice', 'batch', 'title', 'sort', 'split', 'upper', 'lower', 'capitalize', 'filter', 'length', 'merge','format_currency', 'format_number','format_percent_number','map', 'join', 'first', 'date', 'sum', 'number_format','nl2br','striptags','markdown_to_html']; $allowedFunctions = ['range', 'cycle', 'constant', 'date','img','t']; $allowedProperties = ['type_id']; // $allowedMethods = ['img','t']; diff --git a/composer.lock b/composer.lock index 5c7413a6b6..277bf022c2 100644 --- a/composer.lock +++ b/composer.lock @@ -497,16 +497,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.369.15", + "version": "3.369.19", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "7c62f41fb0460c3e5d5c1f70e93e726f1daa75f5" + "reference": "32fee3a25290186724ede9ca177d5090f7c5a837" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7c62f41fb0460c3e5d5c1f70e93e726f1daa75f5", - "reference": "7c62f41fb0460c3e5d5c1f70e93e726f1daa75f5", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/32fee3a25290186724ede9ca177d5090f7c5a837", + "reference": "32fee3a25290186724ede9ca177d5090f7c5a837", "shasum": "" }, "require": { @@ -588,9 +588,9 @@ "support": { "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.369.15" + "source": "https://github.com/aws/aws-sdk-php/tree/3.369.19" }, - "time": "2026-01-16T19:18:57+00:00" + "time": "2026-01-23T19:05:51+00:00" }, { "name": "babenkoivan/elastic-adapter", @@ -1179,16 +1179,16 @@ }, { "name": "btcpayserver/btcpayserver-greenfield-php", - "version": "v2.8.1", + "version": "v2.9.0", "source": { "type": "git", "url": "https://github.com/btcpayserver/btcpayserver-greenfield-php.git", - "reference": "3118f9e4e04590f53b2560866238af463153b2cf" + "reference": "60e6be57f9cd08dbe8f851d056358d1df9f07968" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/btcpayserver/btcpayserver-greenfield-php/zipball/3118f9e4e04590f53b2560866238af463153b2cf", - "reference": "3118f9e4e04590f53b2560866238af463153b2cf", + "url": "https://api.github.com/repos/btcpayserver/btcpayserver-greenfield-php/zipball/60e6be57f9cd08dbe8f851d056358d1df9f07968", + "reference": "60e6be57f9cd08dbe8f851d056358d1df9f07968", "shasum": "" }, "require": { @@ -1227,9 +1227,9 @@ "description": "BTCPay Server Greenfield API PHP client library.", "support": { "issues": "https://github.com/btcpayserver/btcpayserver-greenfield-php/issues", - "source": "https://github.com/btcpayserver/btcpayserver-greenfield-php/tree/v2.8.1" + "source": "https://github.com/btcpayserver/btcpayserver-greenfield-php/tree/v2.9.0" }, - "time": "2024-11-22T16:34:09+00:00" + "time": "2026-01-21T11:31:48+00:00" }, { "name": "carbonphp/carbon-doctrine-types", @@ -2124,16 +2124,16 @@ }, { "name": "dompdf/php-font-lib", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/dompdf/php-font-lib.git", - "reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d" + "reference": "a6e9a688a2a80016ac080b97be73d3e10c444c9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d", - "reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d", + "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/a6e9a688a2a80016ac080b97be73d3e10c444c9a", + "reference": "a6e9a688a2a80016ac080b97be73d3e10c444c9a", "shasum": "" }, "require": { @@ -2141,7 +2141,7 @@ "php": "^7.1 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6" + "phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11 || ^12" }, "type": "library", "autoload": { @@ -2163,9 +2163,9 @@ "homepage": "https://github.com/dompdf/php-font-lib", "support": { "issues": "https://github.com/dompdf/php-font-lib/issues", - "source": "https://github.com/dompdf/php-font-lib/tree/1.0.1" + "source": "https://github.com/dompdf/php-font-lib/tree/1.0.2" }, - "time": "2024-12-02T14:37:59+00:00" + "time": "2026-01-20T14:10:26+00:00" }, { "name": "dompdf/php-svg-lib", @@ -3036,16 +3036,16 @@ }, { "name": "google/apiclient-services", - "version": "v0.428.0", + "version": "v0.429.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "94a3c50a80a36cafb76e32fb76b8007e9f572deb" + "reference": "9dd334c8e6d3f25f91efcab86454c6bc0bc928c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/94a3c50a80a36cafb76e32fb76b8007e9f572deb", - "reference": "94a3c50a80a36cafb76e32fb76b8007e9f572deb", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/9dd334c8e6d3f25f91efcab86454c6bc0bc928c1", + "reference": "9dd334c8e6d3f25f91efcab86454c6bc0bc928c1", "shasum": "" }, "require": { @@ -3074,9 +3074,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.428.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.429.0" }, - "time": "2026-01-12T00:58:26+00:00" + "time": "2026-01-19T01:08:26+00:00" }, { "name": "google/auth", @@ -5085,16 +5085,16 @@ }, { "name": "laravel/framework", - "version": "v11.47.0", + "version": "v11.48.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "86693ffa1ba32f56f8c44e31416c6665095a62c5" + "reference": "5b23ab29087dbcb13077e5c049c431ec4b82f236" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/86693ffa1ba32f56f8c44e31416c6665095a62c5", - "reference": "86693ffa1ba32f56f8c44e31416c6665095a62c5", + "url": "https://api.github.com/repos/laravel/framework/zipball/5b23ab29087dbcb13077e5c049c431ec4b82f236", + "reference": "5b23ab29087dbcb13077e5c049c431ec4b82f236", "shasum": "" }, "require": { @@ -5296,7 +5296,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-11-28T18:20:11+00:00" + "time": "2026-01-20T15:26:20+00:00" }, { "name": "laravel/octane", @@ -6273,16 +6273,16 @@ }, { "name": "league/flysystem", - "version": "3.30.2", + "version": "3.31.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "5966a8ba23e62bdb518dd9e0e665c2dbd4b5b277" + "reference": "1717e0b3642b0df65ecb0cc89cdd99fa840672ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/5966a8ba23e62bdb518dd9e0e665c2dbd4b5b277", - "reference": "5966a8ba23e62bdb518dd9e0e665c2dbd4b5b277", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/1717e0b3642b0df65ecb0cc89cdd99fa840672ff", + "reference": "1717e0b3642b0df65ecb0cc89cdd99fa840672ff", "shasum": "" }, "require": { @@ -6350,22 +6350,22 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.30.2" + "source": "https://github.com/thephpleague/flysystem/tree/3.31.0" }, - "time": "2025-11-10T17:13:11+00:00" + "time": "2026-01-23T15:38:47+00:00" }, { "name": "league/flysystem-aws-s3-v3", - "version": "3.30.1", + "version": "3.31.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git", - "reference": "d286e896083bed3190574b8b088b557b59eb66f5" + "reference": "e36a2bc60b06332c92e4435047797ded352b446f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/d286e896083bed3190574b8b088b557b59eb66f5", - "reference": "d286e896083bed3190574b8b088b557b59eb66f5", + "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/e36a2bc60b06332c92e4435047797ded352b446f", + "reference": "e36a2bc60b06332c92e4435047797ded352b446f", "shasum": "" }, "require": { @@ -6405,22 +6405,22 @@ "storage" ], "support": { - "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.30.1" + "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.31.0" }, - "time": "2025-10-20T15:27:33+00:00" + "time": "2026-01-23T15:30:45+00:00" }, { "name": "league/flysystem-local", - "version": "3.30.2", + "version": "3.31.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "ab4f9d0d672f601b102936aa728801dd1a11968d" + "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/ab4f9d0d672f601b102936aa728801dd1a11968d", - "reference": "ab4f9d0d672f601b102936aa728801dd1a11968d", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/2f669db18a4c20c755c2bb7d3a7b0b2340488079", + "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079", "shasum": "" }, "require": { @@ -6454,9 +6454,9 @@ "local" ], "support": { - "source": "https://github.com/thephpleague/flysystem-local/tree/3.30.2" + "source": "https://github.com/thephpleague/flysystem-local/tree/3.31.0" }, - "time": "2025-11-10T11:23:37+00:00" + "time": "2026-01-23T15:30:45+00:00" }, { "name": "league/fractal", @@ -6844,16 +6844,16 @@ }, { "name": "livewire/livewire", - "version": "v3.7.4", + "version": "v3.7.6", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "5a8dffd4c0ab357ff7ed5b39e7c2453d962a68e0" + "reference": "276ac156f6ae414990784854a2673e3d23c68b24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/5a8dffd4c0ab357ff7ed5b39e7c2453d962a68e0", - "reference": "5a8dffd4c0ab357ff7ed5b39e7c2453d962a68e0", + "url": "https://api.github.com/repos/livewire/livewire/zipball/276ac156f6ae414990784854a2673e3d23c68b24", + "reference": "276ac156f6ae414990784854a2673e3d23c68b24", "shasum": "" }, "require": { @@ -6908,7 +6908,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v3.7.4" + "source": "https://github.com/livewire/livewire/tree/v3.7.6" }, "funding": [ { @@ -6916,7 +6916,7 @@ "type": "github" } ], - "time": "2026-01-13T09:37:21+00:00" + "time": "2026-01-23T05:41:38+00:00" }, { "name": "maennchen/zipstream-php", @@ -16978,16 +16978,16 @@ }, { "name": "twig/extra-bundle", - "version": "v3.22.2", + "version": "v3.23.0", "source": { "type": "git", "url": "https://github.com/twigphp/twig-extra-bundle.git", - "reference": "09de9be7f6c0d19ede7b5a1dbfcfb2e9d1e0ea9e" + "reference": "7a27e784dc56eddfef5e9295829b290ce06f1682" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/09de9be7f6c0d19ede7b5a1dbfcfb2e9d1e0ea9e", - "reference": "09de9be7f6c0d19ede7b5a1dbfcfb2e9d1e0ea9e", + "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/7a27e784dc56eddfef5e9295829b290ce06f1682", + "reference": "7a27e784dc56eddfef5e9295829b290ce06f1682", "shasum": "" }, "require": { @@ -17036,7 +17036,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.22.2" + "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.23.0" }, "funding": [ { @@ -17048,20 +17048,20 @@ "type": "tidelift" } ], - "time": "2025-12-05T08:51:53+00:00" + "time": "2025-12-18T20:46:15+00:00" }, { "name": "twig/intl-extra", - "version": "v3.22.1", + "version": "v3.23.0", "source": { "type": "git", "url": "https://github.com/twigphp/intl-extra.git", - "reference": "93ac31e53cdd3f2e541f42690cd0c54ca8138ab1" + "reference": "32f15a38d45a8d0ec11bc8a3d97d3ac2a261499f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/93ac31e53cdd3f2e541f42690cd0c54ca8138ab1", - "reference": "93ac31e53cdd3f2e541f42690cd0c54ca8138ab1", + "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/32f15a38d45a8d0ec11bc8a3d97d3ac2a261499f", + "reference": "32f15a38d45a8d0ec11bc8a3d97d3ac2a261499f", "shasum": "" }, "require": { @@ -17100,7 +17100,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/intl-extra/tree/v3.22.1" + "source": "https://github.com/twigphp/intl-extra/tree/v3.23.0" }, "funding": [ { @@ -17112,20 +17112,20 @@ "type": "tidelift" } ], - "time": "2025-11-02T11:00:49+00:00" + "time": "2026-01-17T13:57:47+00:00" }, { "name": "twig/markdown-extra", - "version": "v3.22.0", + "version": "v3.23.0", "source": { "type": "git", "url": "https://github.com/twigphp/markdown-extra.git", - "reference": "fb6f952082e3a7d62a75c8be2c8c47242d3925fb" + "reference": "faf069b259e2d3930c73c2f53e2dec8440bd90a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/markdown-extra/zipball/fb6f952082e3a7d62a75c8be2c8c47242d3925fb", - "reference": "fb6f952082e3a7d62a75c8be2c8c47242d3925fb", + "url": "https://api.github.com/repos/twigphp/markdown-extra/zipball/faf069b259e2d3930c73c2f53e2dec8440bd90a2", + "reference": "faf069b259e2d3930c73c2f53e2dec8440bd90a2", "shasum": "" }, "require": { @@ -17172,7 +17172,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/markdown-extra/tree/v3.22.0" + "source": "https://github.com/twigphp/markdown-extra/tree/v3.23.0" }, "funding": [ { @@ -17184,20 +17184,20 @@ "type": "tidelift" } ], - "time": "2025-09-15T05:57:37+00:00" + "time": "2025-12-02T14:45:16+00:00" }, { "name": "twig/twig", - "version": "v3.22.2", + "version": "v3.23.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "946ddeafa3c9f4ce279d1f34051af041db0e16f2" + "reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/946ddeafa3c9f4ce279d1f34051af041db0e16f2", - "reference": "946ddeafa3c9f4ce279d1f34051af041db0e16f2", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9", + "reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9", "shasum": "" }, "require": { @@ -17251,7 +17251,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.22.2" + "source": "https://github.com/twigphp/Twig/tree/v3.23.0" }, "funding": [ { @@ -17263,7 +17263,7 @@ "type": "tidelift" } ], - "time": "2025-12-14T11:28:47+00:00" + "time": "2026-01-23T21:00:41+00:00" }, { "name": "twilio/sdk", @@ -17632,16 +17632,16 @@ "packages-dev": [ { "name": "barryvdh/laravel-debugbar", - "version": "v3.16.3", + "version": "v3.16.5", "source": { "type": "git", "url": "https://github.com/fruitcake/laravel-debugbar.git", - "reference": "c91e57ea113edd6526f5b8cd6b1c6ee02c67b28e" + "reference": "e85c0a8464da67e5b4a53a42796d46a43fc06c9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fruitcake/laravel-debugbar/zipball/c91e57ea113edd6526f5b8cd6b1c6ee02c67b28e", - "reference": "c91e57ea113edd6526f5b8cd6b1c6ee02c67b28e", + "url": "https://api.github.com/repos/fruitcake/laravel-debugbar/zipball/e85c0a8464da67e5b4a53a42796d46a43fc06c9a", + "reference": "e85c0a8464da67e5b4a53a42796d46a43fc06c9a", "shasum": "" }, "require": { @@ -17701,7 +17701,7 @@ ], "support": { "issues": "https://github.com/fruitcake/laravel-debugbar/issues", - "source": "https://github.com/fruitcake/laravel-debugbar/tree/v3.16.3" + "source": "https://github.com/fruitcake/laravel-debugbar/tree/v3.16.5" }, "funding": [ { @@ -17713,7 +17713,7 @@ "type": "github" } ], - "time": "2025-12-23T17:37:00+00:00" + "time": "2026-01-23T15:03:22+00:00" }, { "name": "barryvdh/laravel-ide-helper", @@ -18411,16 +18411,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.92.5", + "version": "v3.93.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "260cc8c4a1d2f6d2f22cd4f9c70aa72e55ebac58" + "reference": "50895a07cface1385082e4caa6a6786c4e033468" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/260cc8c4a1d2f6d2f22cd4f9c70aa72e55ebac58", - "reference": "260cc8c4a1d2f6d2f22cd4f9c70aa72e55ebac58", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/50895a07cface1385082e4caa6a6786c4e033468", + "reference": "50895a07cface1385082e4caa6a6786c4e033468", "shasum": "" }, "require": { @@ -18452,14 +18452,14 @@ }, "require-dev": { "facile-it/paraunit": "^1.3.1 || ^2.7", - "infection/infection": "^0.31", + "infection/infection": "^0.32", "justinrainbow/json-schema": "^6.6", "keradus/cli-executor": "^2.3", "mikey179/vfsstream": "^1.6.12", "php-coveralls/php-coveralls": "^2.9", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", - "phpunit/phpunit": "^9.6.31 || ^10.5.60 || ^11.5.46", + "phpunit/phpunit": "^9.6.31 || ^10.5.60 || ^11.5.48", "symfony/polyfill-php85": "^1.33", "symfony/var-dumper": "^5.4.48 || ^6.4.26 || ^7.4.0 || ^8.0", "symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0" @@ -18503,7 +18503,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.92.5" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.93.0" }, "funding": [ { @@ -18511,7 +18511,7 @@ "type": "github" } ], - "time": "2026-01-08T21:57:37+00:00" + "time": "2026-01-23T17:33:21+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -18607,7 +18607,7 @@ }, { "name": "illuminate/json-schema", - "version": "v12.47.0", + "version": "v12.48.1", "source": { "type": "git", "url": "https://github.com/illuminate/json-schema.git", @@ -21675,38 +21675,39 @@ }, { "name": "spatie/laravel-ignition", - "version": "2.9.1", + "version": "2.10.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-ignition.git", - "reference": "1baee07216d6748ebd3a65ba97381b051838707a" + "reference": "2abefdcca6074a9155f90b4ccb3345af8889d5f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/1baee07216d6748ebd3a65ba97381b051838707a", - "reference": "1baee07216d6748ebd3a65ba97381b051838707a", + "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/2abefdcca6074a9155f90b4ccb3345af8889d5f5", + "reference": "2abefdcca6074a9155f90b4ccb3345af8889d5f5", "shasum": "" }, "require": { "ext-curl": "*", "ext-json": "*", "ext-mbstring": "*", - "illuminate/support": "^10.0|^11.0|^12.0", - "php": "^8.1", - "spatie/ignition": "^1.15", - "symfony/console": "^6.2.3|^7.0", - "symfony/var-dumper": "^6.2.3|^7.0" + "illuminate/support": "^11.0|^12.0", + "nesbot/carbon": "^2.72|^3.0", + "php": "^8.2", + "spatie/ignition": "^1.15.1", + "symfony/console": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0" }, "require-dev": { - "livewire/livewire": "^2.11|^3.3.5", - "mockery/mockery": "^1.5.1", - "openai-php/client": "^0.8.1|^0.10", - "orchestra/testbench": "8.22.3|^9.0|^10.0", - "pestphp/pest": "^2.34|^3.7", - "phpstan/extension-installer": "^1.3.1", - "phpstan/phpstan-deprecation-rules": "^1.1.1|^2.0", - "phpstan/phpstan-phpunit": "^1.3.16|^2.0", - "vlucas/phpdotenv": "^5.5" + "livewire/livewire": "^3.7.0|^4.0", + "mockery/mockery": "^1.6.12", + "openai-php/client": "^0.10.3", + "orchestra/testbench": "^v9.16.0|^10.6", + "pestphp/pest": "^3.7|^4.0", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan-deprecation-rules": "^2.0.3", + "phpstan/phpstan-phpunit": "^2.0.8", + "vlucas/phpdotenv": "^5.6.2" }, "suggest": { "openai-php/client": "Require get solutions from OpenAI", @@ -21762,7 +21763,7 @@ "type": "github" } ], - "time": "2025-02-20T13:13:55+00:00" + "time": "2026-01-20T13:16:11+00:00" }, { "name": "spaze/phpstan-stripe", diff --git a/config/ninja.php b/config/ninja.php index 55ff879f20..da8a268256 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -17,8 +17,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => env('APP_VERSION', '5.12.48'), - 'app_tag' => env('APP_TAG', '5.12.48'), + 'app_version' => env('APP_VERSION', '5.12.49'), + 'app_tag' => env('APP_TAG', '5.12.49'), 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', false), diff --git a/lang/fr_CA/texts.php b/lang/fr_CA/texts.php index d717ecff38..80fe92c669 100644 --- a/lang/fr_CA/texts.php +++ b/lang/fr_CA/texts.php @@ -5689,6 +5689,7 @@ Développe automatiquement la section des notes dans le tableau de produits pour 'peppol_sending_failed' => 'Problème technique de livraison. Réessai impossible.', 'peppol_sending_success' => 'La facture électronique a été envoyée!', 'auto_generate' => 'Auto générer', + 'mollie_payment_pending' => 'Votre paiement est en attente. Veuillez patienter pendant son traitement. Nous vous enverrons un e-mail une fois qu\'il sera terminé.', ); return $lang; diff --git a/lang/vi/texts.php b/lang/vi/texts.php index 084a9e3cd4..dec5f6ec97 100644 --- a/lang/vi/texts.php +++ b/lang/vi/texts.php @@ -5690,6 +5690,7 @@ $lang = array( 'peppol_sending_failed' => 'Sự cố giao hàng kỹ thuật. Không thể thử lại', 'peppol_sending_success' => 'E- Hóa đơn gửi Thành công !', 'auto_generate' => 'Tự động tạo', + 'mollie_payment_pending' => 'Sự chi trả của bạn đang chờ xử lý. Vui lòng chờ đến xử lý. Chúng tôi sẽ email cho bạn khi hoàn tất.', ); return $lang; diff --git a/lang/zh_TW/texts.php b/lang/zh_TW/texts.php index a1cd23f1f7..f791e973d3 100644 --- a/lang/zh_TW/texts.php +++ b/lang/zh_TW/texts.php @@ -60,8 +60,8 @@ $lang = array( 'download_pdf' => '下載 PDF', 'pay_now' => '立即付款', 'save_invoice' => '儲存發票', - 'clone_invoice' => '克隆至發票', - 'archive_invoice' => '存檔發票', + 'clone_invoice' => '複製至發票', + 'archive_invoice' => '歸檔發票', 'delete_invoice' => '刪除發票', 'email_invoice' => '電郵發票', 'enter_payment' => '輸入付款', @@ -75,7 +75,7 @@ $lang = array( 'clients' => '客戶', 'invoices' => '發票', 'payments' => '付款', - 'credits' => '貸款', + 'credits' => '信用', 'history' => '歷史', 'search' => '搜尋', 'sign_up' => '報名', @@ -88,14 +88,14 @@ $lang = array( 'save' => '儲存', 'create' => '創造', 'upload' => '上傳', - 'import' => '進口', + 'import' => '匯入', 'download' => '下載', 'cancel' => '取消', 'close' => '關閉', 'provide_email' => '請提供有效的電子郵件地址', 'powered_by' => '供電', 'no_items' => '沒有項目', - 'recurring_invoices' => '定期發票', + 'recurring_invoices' => '週期發票', 'recurring_help' => '
每週、每兩個月、每月、每季或每年自動向客戶發送相同的發票。
使用:MONTH 、 :QUARTER或:YEAR取得動態日期。基本數學也同樣有效,例如:MONTH -1。
動態發票變數的範例:
@@ -104,7 +104,7 @@ $lang = array(Label|Option1,Option2 以顯示選取方塊。',
'client_information' => '用戶資訊',
'updated_client_details' => '更新用戶詳細資料成功',
@@ -2687,7 +2687,7 @@ $lang = array(
'icon' => '圖示',
'proposal_not_found' => '無法提供查詢的提案',
'create_proposal_category' => '建立類別',
- 'clone_proposal_template' => '再製範本',
+ 'clone_proposal_template' => '複製範本',
'proposal_email' => '提案的電子郵件',
'proposal_subject' => ':account 的新提案 :number',
'proposal_message' => '若要檢視您的 :amount 之提案,按一下以下連結。',
@@ -2738,7 +2738,7 @@ $lang = array(
'invalid_url' => '無效的 URL',
'workflow_settings' => '工作流程設定',
'auto_email_invoice' => '自動電子郵件',
- 'auto_email_invoice_help' => '建立後自動透過電子郵件發送定期發票。',
+ 'auto_email_invoice_help' => '建立後自動透過電子郵件發送週期發票。',
'auto_archive_invoice' => '自動歸檔',
'auto_archive_invoice_help' => '付款後自動存檔發票。',
'auto_archive_quote' => '自動歸檔',
@@ -2753,11 +2753,11 @@ $lang = array(
'purge_client' => '清除用戶',
'purged_client' => '清除用戶成功',
'purge_client_warning' => '所有相關的紀錄 (發票、任務、支出、文件等等) 也將會刪除。',
- 'clone_product' => '再製產品資料',
+ 'clone_product' => '複製產品資料',
'item_details' => '項目詳細資料',
'send_item_details_help' => '將單項產品的詳細資料傳送到付款主頁面。',
'view_proposal' => '檢視提案',
- 'view_in_portal' => '在入口頁面檢視',
+ 'view_in_portal' => '在客戶端檢視',
'cookie_message' => '本網站使用 cookies 以確保您能在此得到最佳的使用經驗。',
'got_it' => '瞭解了!',
'vendor_will_create' => '將建立供應商',
@@ -2960,8 +2960,8 @@ $lang = array(
'previous_year' => '上一年度',
'compare_to' => '比較',
'last_week' => '上個星期',
- 'clone_to_invoice' => '再製到發票',
- 'clone_to_quote' => '再製到報價單',
+ 'clone_to_invoice' => '複製到發票',
+ 'clone_to_quote' => '複製到報價單',
'convert' => '轉換',
'last7_days' => '最近 7 天',
'last30_days' => '最近 30 天',
@@ -2997,7 +2997,7 @@ $lang = array(
'edit_document' => '編輯文件',
'uploaded_document' => '已成功上載文件',
'updated_document' => '已成功更新文件',
- 'archived_document' => '已成功封存文件',
+ 'archived_document' => '已成功歸檔文件',
'deleted_document' => '已成功刪除文件',
'restored_document' => '已成功還原文件',
'no_history' => '無歷史記錄',
@@ -3043,7 +3043,7 @@ $lang = array(
'number_counter' => '數字計數器',
'number_pattern' => '數字模式',
'custom_javascript' => '自訂 JavaScript',
- 'portal_mode' => '入口網站模式',
+ 'portal_mode' => '客戶端模式',
'attach_pdf' => '附上PDF',
'attach_documents' => '附加文件',
'attach_ubl' => '附上 UBL/電子發票',
@@ -3065,7 +3065,7 @@ $lang = array(
'edit_company_gateway' => '編輯閘道',
'created_company_gateway' => '建立閘道資料成功',
'updated_company_gateway' => '更新閘道資料成功',
- 'archived_company_gateway' => '封存閘道資料成功',
+ 'archived_company_gateway' => '歸檔閘道資料成功',
'deleted_company_gateway' => '刪除閘道資料成功',
'restored_company_gateway' => '復原閘道成功',
'continue_editing' => '繼續編輯',
@@ -3089,7 +3089,7 @@ $lang = array(
'edit_group' => '編輯群組',
'created_group' => '已成功建立群組',
'updated_group' => '已成功更新群組',
- 'archived_group' => '已成功封存群組',
+ 'archived_group' => '已成功歸檔群組',
'deleted_group' => '已成功刪除群組',
'restored_group' => '已成功還原群組',
'upload_logo' => '上傳您的公司徽標',
@@ -3188,7 +3188,7 @@ $lang = array(
'domain_url' => '網域網址',
'password_is_too_easy' => '密碼必須包含大寫字元和數字',
'client_portal_tasks' => '客戶端任務',
- 'client_portal_dashboard' => '客戶入口網站儀表板',
+ 'client_portal_dashboard' => '客戶端儀表板',
'please_enter_a_value' => '請輸入一個值',
'deleted_logo' => '成功刪除標誌',
'generate_number' => '產生號碼',
@@ -3290,7 +3290,7 @@ $lang = array(
'tax_rate1' => '稅率1',
'tax_rate2' => '稅率2',
'tax_rate3' => '稅率3',
- 'archived_at' => '存檔於',
+ 'archived_at' => '歸檔於',
'has_expenses' => '有費用',
'custom_taxes1' => '關稅 1',
'custom_taxes2' => '關稅 2',
@@ -3361,14 +3361,14 @@ $lang = array(
'slack_webhook_url' => 'Slack Webhook URL',
'partial_payment' => '部分付款',
'partial_payment_email' => '部分付款電子郵件',
- 'clone_to_credit' => '克隆到信用',
+ 'clone_to_credit' => '複製到信用',
'emailed_credit' => '已成功透過電子郵件發送信用證',
'marked_credit_as_sent' => '已成功將信用標記為已發送',
'email_subject_payment_partial' => '電子郵件部分付款主題',
'is_approved' => '被批准',
'migration_went_wrong' => '哎呀!出事了!在開始遷移之前,請確保您已設定 Invoice Ninja v5 實例。',
'cross_migration_message' => '不允許跨帳戶遷移。請在此閱讀更多相關資訊: https ://invoiceninja.github.io/docs/migration/#troubleshooting',
- 'email_credit' => '電子郵件信用',
+ 'email_credit' => '電郵信用',
'client_email_not_set' => '客戶沒有設定電子郵件地址',
'ledger' => '分類帳',
'view_pdf' => '查看PDF',
@@ -3514,7 +3514,7 @@ $lang = array(
'removed_token' => '成功刪除令牌',
'restored_token' => '成功恢復令牌',
'client_registration' => '客戶註冊',
- 'client_registration_help' => '使客戶能夠在入口網站中自行註冊',
+ 'client_registration_help' => '使客戶能夠在客戶端中自行註冊',
'customize_and_preview' => '客製化和預覽',
'search_document' => '搜尋 1 個文檔',
'search_design' => '搜尋 1 設計',
@@ -3544,7 +3544,7 @@ $lang = array(
'add_documents_to_invoice_help' => '使文件對客戶可見',
'convert_currency_help' => '設定匯率',
'expense_settings' => '費用設定',
- 'clone_to_recurring' => '克隆到重複',
+ 'clone_to_recurring' => '複製到重複',
'crypto' => '加密貨幣',
'user_field' => '使用者欄位',
'variables' => '變數',
@@ -3556,9 +3556,9 @@ $lang = array(
'total_taxes' => '總稅金',
'line_taxes' => '行稅',
'total_fields' => '總字段數',
- 'stopped_recurring_invoice' => '已成功停止定期發票',
- 'started_recurring_invoice' => '已成功開始定期發票',
- 'resumed_recurring_invoice' => '已成功恢復定期發票',
+ 'stopped_recurring_invoice' => '已成功停止週期發票',
+ 'started_recurring_invoice' => '已成功開始週期發票',
+ 'resumed_recurring_invoice' => '已成功恢復週期發票',
'gateway_refund' => '網關退款',
'gateway_refund_help' => '透過支付網關處理退款',
'due_date_days' => '到期日',
@@ -3570,11 +3570,11 @@ $lang = array(
'endless' => '無盡',
'next_send_date' => '下次發送日期',
'remaining_cycles' => '剩餘週期',
- 'created_recurring_invoice' => '已成功建立定期發票',
- 'updated_recurring_invoice' => '已成功更新定期發票',
+ 'created_recurring_invoice' => '已成功建立週期發票',
+ 'updated_recurring_invoice' => '已成功更新週期發票',
'removed_recurring_invoice' => '已成功刪除定期發票',
- 'search_recurring_invoice' => '搜尋 1 份經常性發票',
- 'search_recurring_invoices' => '搜尋:count經常性發票',
+ 'search_recurring_invoice' => '搜尋 1 份週期性發票',
+ 'search_recurring_invoices' => '搜尋:count週期性發票',
'send_date' => '發送日期',
'auto_bill_on' => '自動計費開啟',
'minimum_under_payment_amount' => '最低付款金額',
@@ -3649,8 +3649,8 @@ $lang = array(
'sidebar_editor' => '側邊欄編輯器',
'please_type_to_confirm' => '請輸入「 :value 」確認',
'purge' => '清除',
- 'clone_to' => '克隆到',
- 'clone_to_other' => '克隆到其他',
+ 'clone_to' => '複製到',
+ 'clone_to_other' => '複製到其他',
'labels' => '標籤',
'add_custom' => '新增自訂',
'payment_tax' => '繳稅',
@@ -3659,26 +3659,26 @@ $lang = array(
'paid_invoices_are_locked' => '已付款發票已鎖定',
'source_code' => '原始碼',
'app_platforms' => '應用程式平台',
- 'archived_task_statuses' => '已成功存檔:value任務狀態',
+ 'archived_task_statuses' => '已成功歸檔:value任務狀態',
'deleted_task_statuses' => '已成功刪除:value任務狀態',
'restored_task_statuses' => '成功恢復:value任務狀態',
'deleted_expense_categories' => '已成功刪除費用:value類別',
'restored_expense_categories' => '成功恢復費用:value類別',
- 'archived_recurring_invoices' => '已成功存檔定期:value發票',
- 'deleted_recurring_invoices' => '已成功刪除定期:value發票',
- 'restored_recurring_invoices' => '已成功恢復定期:value發票',
- 'archived_webhooks' => '已成功存檔:value webhooks',
+ 'archived_recurring_invoices' => '已成功歸檔週期:value發票',
+ 'deleted_recurring_invoices' => '已成功刪除週期:value發票',
+ 'restored_recurring_invoices' => '已成功恢復週期:value發票',
+ 'archived_webhooks' => '已成功歸檔:value webhooks',
'deleted_webhooks' => '已成功刪除:value webhooks',
'removed_webhooks' => '已成功刪除:value webhooks',
'restored_webhooks' => '已成功恢復:value webhooks',
'api_docs' => 'API文件',
- 'archived_tokens' => '已成功存檔:value令牌',
+ 'archived_tokens' => '已成功歸檔:value令牌',
'deleted_tokens' => '已成功刪除:value令牌',
'restored_tokens' => '已成功恢復:value令牌',
- 'archived_payment_terms' => '已成功存檔:value付款條件',
+ 'archived_payment_terms' => '已成功歸檔:value付款條件',
'deleted_payment_terms' => '已成功刪除:value付款條件',
'restored_payment_terms' => '已成功恢復:value付款條件',
- 'archived_designs' => '成功存檔:value設計',
+ 'archived_designs' => '成功歸檔:value設計',
'deleted_designs' => '成功刪除:value設計',
'restored_designs' => '成功恢復:value設計',
'restored_credits' => '已成功恢復:value積分',
@@ -3686,13 +3686,13 @@ $lang = array(
'deleted_users' => '已成功刪除:value用戶',
'removed_users' => '已成功刪除:value用戶',
'restored_users' => '成功恢復:value用戶',
- 'archived_tax_rates' => '成功存檔:value稅率',
+ 'archived_tax_rates' => '成功歸檔:value稅率',
'deleted_tax_rates' => '已成功刪除:value稅率',
'restored_tax_rates' => '成功恢復:value稅率',
- 'archived_company_gateways' => '已成功存檔:value網關',
+ 'archived_company_gateways' => '已成功歸檔:value網關',
'deleted_company_gateways' => '已成功刪除:value網關',
'restored_company_gateways' => '成功恢復:value網關',
- 'archived_groups' => '已成功存檔:value組',
+ 'archived_groups' => '已成功歸檔:value組',
'deleted_groups' => '已成功刪除:value組',
'restored_groups' => '成功恢復:value組',
'archived_documents' => '已成功歸檔:value文檔',
@@ -3799,10 +3799,10 @@ $lang = array(
'list_of_invoices' => '發票清單',
'with_selected' => '與選定的',
'invoice_still_unpaid' => '該發票仍未支付。點擊按鈕完成付款',
- 'list_of_recurring_invoices' => '經常性發票清單',
- 'details_of_recurring_invoice' => '以下是有關定期發票的一些詳細信息',
+ 'list_of_recurring_invoices' => '週期性發票清單',
+ 'details_of_recurring_invoice' => '以下是有關週期發票的一些詳細信息',
'cancellation' => '消除',
- 'about_cancellation' => '如果您想停止定期發票,請點選請求取消。',
+ 'about_cancellation' => '如果您想停止週期發票,請點選請求取消。',
'cancellation_warning' => '警告!您請求取消此服務。您的服務可能會被取消,恕不另行通知。',
'cancellation_pending' => '取消待定,我們會聯絡您!',
'list_of_payments' => '付款清單',
@@ -3880,7 +3880,7 @@ $lang = array(
'under_payments_disabled' => '本公司不支援少付款。',
'over_payments_disabled' => '本公司不支援超額付款。',
'saved_at' => '保存於:time',
- 'credit_payment' => '貸記應用於發票:invoice _number',
+ 'credit_payment' => '信用應用於發票:invoice _number',
'credit_subject' => '來自:account的新信用:number',
'credit_message' => '要查看:amount的積分,請點擊下面的連結。',
'payment_type_Crypto' => '加密貨幣',
@@ -3936,7 +3936,7 @@ $lang = array(
'max_refundable_credit' => '嘗試退款超過允許的信用額:credit ,最大可退款金額為:amount',
'project_client_do_not_match' => '專案客戶與實體客戶不匹配',
'quote_number_taken' => '報價單號碼已被佔用',
- 'recurring_invoice_number_taken' => '經常性發票編號:number已使用',
+ 'recurring_invoice_number_taken' => '週期性發票編號:number已使用',
'user_not_associated_with_account' => '使用者未與此帳戶關聯',
'amounts_do_not_balance' => '金額未正確平衡。',
'insufficient_applied_amount_remaining' => '剩餘申請金額不足以支付付款。',
@@ -3951,7 +3951,7 @@ $lang = array(
'large_account_update_parameter' => '如果沒有 update_at 參數,則無法載入大型帳戶',
'no_backup_exists' => '此活動不存在備份',
'company_user_not_found' => '未找到公司用戶記錄',
- 'no_credits_found' => '沒有找到學分。',
+ 'no_credits_found' => '沒有找到信用。',
'action_unavailable' => '請求的操作:action不可用。',
'no_documents_found' => '沒有找到文件',
'no_group_settings_found' => '未找到組設定',
@@ -3979,14 +3979,14 @@ $lang = array(
'start_multiselect' => '開始多選',
'email_sent_to_confirm_email' => '已發送一封電子郵件以確認電子郵件地址',
'converted_paid_to_date' => '轉換為付費日期',
- 'converted_credit_balance' => '轉換後的貸方餘額',
+ 'converted_credit_balance' => '轉換後的信用方餘額',
'converted_total' => '換算總計',
'reply_to_name' => '回覆名稱',
'payment_status_-2' => '部分未應用',
'color_theme' => '顏色主題',
'start_migration' => '開始遷移',
- 'recurring_cancellation_request' => ':contact請求取消定期發票',
- 'recurring_cancellation_request_body' => '客戶:contact請求取消經常:client發票:invoice',
+ 'recurring_cancellation_request' => ':contact請求取消週期發票',
+ 'recurring_cancellation_request_body' => '客戶:contact請求取消週期:client發票:invoice',
'hello' => '你好',
'group_documents' => '集團文件',
'quote_approval_confirmation_label' => '您確定要批准此報價嗎?',
@@ -4015,7 +4015,7 @@ $lang = array(
'billing_coupon_notice' => '您的折扣將在結帳時套用。',
'use_last_email' => '使用最後的電子郵件',
'activate_company' => '啟動公司',
- 'activate_company_help' => '啟用電子郵件、定期發票和通知',
+ 'activate_company_help' => '啟用電子郵件、週期發票和通知',
'an_error_occurred_try_again' => '發生錯誤,請重試',
'please_first_set_a_password' => '請先設定密碼',
'changing_phone_disables_two_factor' => '警告:更改您的電話號碼將停用 2FA',
@@ -4036,7 +4036,7 @@ $lang = array(
'invoice_task_datelog' => '發票任務日期日誌',
'invoice_task_datelog_help' => '將日期詳細資料新增至發票行項目',
'promo_code' => '促銷代碼',
- 'recurring_invoice_issued_to' => '定期發票開立至',
+ 'recurring_invoice_issued_to' => '週期發票開立至',
'subscription' => '訂閱',
'new_subscription' => '新訂閱',
'deleted_subscription' => '已成功刪除訂閱',
@@ -4056,7 +4056,7 @@ $lang = array(
'shared_invoice_credit_counter' => '共享發票/信用櫃檯',
'activity_80' => ':user建立訂閱:subscription',
'activity_81' => ':user更新訂閱:subscription',
- 'activity_82' => ':user存檔訂閱:subscription',
+ 'activity_82' => ':user歸檔訂閱:subscription',
'activity_83' => ':user已刪除訂閱:subscription',
'activity_84' => ':user恢復訂閱:subscription',
'amount_greater_than_balance_v5' => '金額大於發票餘額。您不能多付發票費用。',
@@ -4073,11 +4073,11 @@ $lang = array(
'migration_already_completed_desc' => '看起來您已經將:company _name遷移到 Invoice Ninja 的 V5 版本了。如果您想重新開始,可以強制遷移以擦除現有資料。',
'payment_method_cannot_be_authorized_first' => '完成第一筆交易後,可以儲存此付款方式以供將來使用。不要忘記在付款過程中檢查“商店詳細資料”。',
'new_account' => '新帳戶',
- 'activity_100' => ':user創建了定期發票:recurring_invoice',
- 'activity_101' => ':user更新的經常性發票:recurring_invoice',
- 'activity_102' => ':user存檔的經常性發票:recurring_invoice',
- 'activity_103' => ':user刪除定期發票:recurring_invoice',
- 'activity_104' => ':user恢復定期發票:recurring_invoice',
+ 'activity_100' => ':user創建了週期發票:recurring_invoice',
+ 'activity_101' => ':user更新的週期性發票:recurring_invoice',
+ 'activity_102' => ':user歸檔的週期性發票:recurring_invoice',
+ 'activity_103' => ':user刪除週期發票:recurring_invoice',
+ 'activity_104' => ':user恢復週期發票:recurring_invoice',
'new_login_detected' => '偵測到您的帳戶有新的登入資訊。',
'new_login_description' => '您最近從新位置或裝置登入了您的 Invoice Ninja 帳戶: