Compare commits
107 Commits
2.2.0
...
backport-r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
525f432ee0 | ||
|
|
f17c7be5f0 | ||
|
|
0e9f18d4d1 | ||
|
|
e22050bc71 | ||
|
|
af9d672574 | ||
|
|
7606f8ece8 | ||
|
|
9b0498a2e5 | ||
|
|
04c7682e73 | ||
|
|
88650c2f3e | ||
|
|
ee76f31138 | ||
|
|
e1af9f56c4 | ||
|
|
fdd860c381 | ||
|
|
834b53ea40 | ||
|
|
5ff051fbb5 | ||
|
|
0d7059fcf6 | ||
|
|
7d9fdb79cc | ||
|
|
3d871604ae | ||
|
|
1adebe85b9 | ||
|
|
defbfc6406 | ||
|
|
25986b7bd5 | ||
|
|
751bd4a1c8 | ||
|
|
0e313b80ca | ||
|
|
5014a75fbc | ||
|
|
9e5b9fdaad | ||
|
|
08dfe62312 | ||
|
|
f623cd0179 | ||
|
|
77fd96d499 | ||
|
|
2e4e19dfc5 | ||
|
|
76c02be219 | ||
|
|
414531524c | ||
|
|
d75a957183 | ||
|
|
63d3a7fc8e | ||
|
|
0be747a483 | ||
|
|
3ceb08bc31 | ||
|
|
ad5a7e51b9 | ||
|
|
691178857f | ||
|
|
a38f09cf7b | ||
|
|
de4ba6bba0 | ||
|
|
375cfc6b18 | ||
|
|
aa88dc340d | ||
|
|
7004bf375e | ||
|
|
80889293bf | ||
|
|
d754c4d29e | ||
|
|
8de32e27d3 | ||
|
|
0f933b6217 | ||
|
|
3bae2c282c | ||
|
|
14b5aaa0c9 | ||
|
|
241ec09220 | ||
|
|
ed7af3fc3c | ||
|
|
aafcf147cf | ||
|
|
7e8f9e65fb | ||
|
|
67739750ca | ||
|
|
5f6a7b92bf | ||
|
|
ff3cab570a | ||
|
|
11024ddc38 | ||
|
|
71303a1050 | ||
|
|
3af0e83d26 | ||
|
|
a866a26e9f | ||
|
|
154a4dc076 | ||
|
|
7900e020f5 | ||
|
|
974efb36da | ||
|
|
45d84b8b3c | ||
|
|
fdfb46ed79 | ||
|
|
ddcef0fb2c | ||
|
|
0254b16556 | ||
|
|
a9a52ca85f | ||
|
|
708d880b52 | ||
|
|
57406989d4 | ||
|
|
5d7e46b026 | ||
|
|
8e034e59f8 | ||
|
|
43951d4542 | ||
|
|
3cc0f41d8c | ||
|
|
5f34ae558c | ||
|
|
70d51d580d | ||
|
|
b7929672fb | ||
|
|
bd28849a9f | ||
|
|
4d21aadcd4 | ||
|
|
373a824fdb | ||
|
|
a5d9a60d5c | ||
|
|
2537b53506 | ||
|
|
bbc2d2088a | ||
|
|
5734a06ab3 | ||
|
|
75a1038245 | ||
|
|
017691b7b1 | ||
|
|
d4f8a40982 | ||
|
|
ebdee1e3f0 | ||
|
|
ce97a474f9 | ||
|
|
4ee3d0d129 | ||
|
|
bd5abdec0e | ||
|
|
995533974e | ||
|
|
156e94f931 | ||
|
|
e38c4963ef | ||
|
|
d7efbb5c47 | ||
|
|
3cd219e7b3 | ||
|
|
3d65a09038 | ||
|
|
f52c376a49 | ||
|
|
5a7c1363ee | ||
|
|
2c40c2ef06 | ||
|
|
b5ff16c318 | ||
|
|
4d7b818d23 | ||
|
|
b314ebc07f | ||
|
|
254ed5ade0 | ||
|
|
40e4ea931e | ||
|
|
3c31baf20d | ||
|
|
a386fd19fc | ||
|
|
e5f6984078 | ||
|
|
d2953e9409 |
@@ -10,7 +10,7 @@ metadata:
|
||||
|
||||
## Documentation
|
||||
|
||||
Use `search-docs` for detailed Tailwind CSS v3 patterns and documentation.
|
||||
Use `search-docs` for detailed Tailwind CSS v4 patterns and documentation.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
@@ -18,22 +18,55 @@ Use `search-docs` for detailed Tailwind CSS v3 patterns and documentation.
|
||||
- Offer to extract repeated patterns into components that match the project's conventions (e.g., Blade, JSX, Vue).
|
||||
- Consider class placement, order, priority, and defaults. Remove redundant classes, add classes to parent or child elements carefully to reduce repetition, and group elements logically.
|
||||
|
||||
## Tailwind CSS v3 Specifics
|
||||
## Tailwind CSS v4 Specifics
|
||||
|
||||
- Always use Tailwind CSS v3 and verify you're using only classes it supports.
|
||||
- Configuration is done in the `tailwind.config.js` file.
|
||||
- Import using `@tailwind` directives:
|
||||
- Always use Tailwind CSS v4 and avoid deprecated utilities.
|
||||
- `corePlugins` is not supported in Tailwind v4.
|
||||
|
||||
<!-- v3 Import Syntax -->
|
||||
### CSS-First Configuration
|
||||
|
||||
In Tailwind v4, configuration is CSS-first using the `@theme` directive — no separate `tailwind.config.js` file is needed:
|
||||
|
||||
<!-- CSS-First Config -->
|
||||
```css
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@theme {
|
||||
--color-brand: oklch(0.72 0.11 178);
|
||||
}
|
||||
```
|
||||
|
||||
### Import Syntax
|
||||
|
||||
In Tailwind v4, import Tailwind with a regular CSS `@import` statement instead of the `@tailwind` directives used in v3:
|
||||
|
||||
<!-- v4 Import Syntax -->
|
||||
```diff
|
||||
- @tailwind base;
|
||||
- @tailwind components;
|
||||
- @tailwind utilities;
|
||||
+ @import "tailwindcss";
|
||||
```
|
||||
|
||||
### Replaced Utilities
|
||||
|
||||
Tailwind v4 removed deprecated utilities. Use the replacements shown below. Opacity values remain numeric.
|
||||
|
||||
| Deprecated | Replacement |
|
||||
|------------|-------------|
|
||||
| bg-opacity-* | bg-black/* |
|
||||
| text-opacity-* | text-black/* |
|
||||
| border-opacity-* | border-black/* |
|
||||
| divide-opacity-* | divide-black/* |
|
||||
| ring-opacity-* | ring-black/* |
|
||||
| placeholder-opacity-* | placeholder-black/* |
|
||||
| flex-shrink-* | shrink-* |
|
||||
| flex-grow-* | grow-* |
|
||||
| overflow-ellipsis | text-ellipsis |
|
||||
| decoration-slice | box-decoration-slice |
|
||||
| decoration-clone | box-decoration-clone |
|
||||
|
||||
## Spacing
|
||||
|
||||
When listing items, use gap utilities for spacing; don't use margins.
|
||||
Use `gap` utilities instead of margins for spacing between siblings:
|
||||
|
||||
<!-- Gap Utilities -->
|
||||
```html
|
||||
@@ -77,15 +110,10 @@ If existing pages and components support dark mode, new pages and components mus
|
||||
</div>
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
1. Check browser for visual rendering
|
||||
2. Test responsive breakpoints
|
||||
3. Verify dark mode if project uses it
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
- Using deprecated v3 utilities (bg-opacity-*, flex-shrink-*, etc.)
|
||||
- Using `@tailwind` directives instead of `@import "tailwindcss"`
|
||||
- Trying to use `tailwind.config.js` instead of CSS `@theme` directive
|
||||
- Using margins for spacing between siblings instead of gap utilities
|
||||
- Forgetting to add dark mode variants when the project uses dark mode
|
||||
- Not checking existing project conventions before adding new utilities
|
||||
- Overusing inline styles when Tailwind classes would suffice
|
||||
- Forgetting to add dark mode variants when the project uses dark mode
|
||||
@@ -1,14 +0,0 @@
|
||||
// .eslintrc.js
|
||||
|
||||
module.exports = {
|
||||
extends: [
|
||||
// add more generic rulesets here, such as:
|
||||
// 'eslint:recommended',
|
||||
"plugin:vue/vue3-recommended",
|
||||
"prettier",
|
||||
],
|
||||
rules: {
|
||||
// override/add rules settings here, such as:
|
||||
// 'vue/no-unused-vars': 'error'
|
||||
},
|
||||
};
|
||||
18
.github/release.yml
vendored
Normal file
18
.github/release.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
changelog:
|
||||
categories:
|
||||
- title: New Features
|
||||
labels:
|
||||
- enhancement
|
||||
- feature
|
||||
- title: Bug Fixes
|
||||
labels:
|
||||
- bug
|
||||
- fix
|
||||
- title: Maintenance
|
||||
labels:
|
||||
- chore
|
||||
- dependencies
|
||||
- ci
|
||||
- title: Other Changes
|
||||
labels:
|
||||
- "*"
|
||||
43
.github/workflows/check.yaml
vendored
43
.github/workflows/check.yaml
vendored
@@ -3,28 +3,41 @@ name: Check
|
||||
# Run this workflow every time a new commit pushed to your repository
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- '.github/**/*'
|
||||
- '**/*.md'
|
||||
- 'public/build/*.js'
|
||||
- 'public/build/**/*.js'
|
||||
- 'docker/**/*'
|
||||
- 'resources/scripts/**/*'
|
||||
tags-ignore:
|
||||
- "*"
|
||||
branches-ignore:
|
||||
- 'translations'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- 'public/build/*.js'
|
||||
- 'public/build/**/*.js'
|
||||
branches-ignore:
|
||||
- 'translations'
|
||||
# Allow manually triggering the workflow.
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
name: 🔍 Detect changes
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
php: ${{ steps.filter.outputs.php }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check for file changes
|
||||
uses: dorny/paths-filter@v3
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
php:
|
||||
- 'app/**'
|
||||
- 'config/**'
|
||||
- 'database/**'
|
||||
- 'routes/**'
|
||||
- 'tests/**'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
- 'phpunit.xml'
|
||||
|
||||
kill_previous:
|
||||
name: 0️⃣ Kill previous runs
|
||||
runs-on: ubuntu-latest
|
||||
@@ -41,6 +54,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- kill_previous
|
||||
- changes
|
||||
if: needs.changes.outputs.php == 'true'
|
||||
steps:
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
@@ -60,6 +75,8 @@ jobs:
|
||||
name: 2️⃣ PHP ${{ matrix.php-version }} Tests
|
||||
needs:
|
||||
- php_syntax_errors
|
||||
- changes
|
||||
if: needs.changes.outputs.php == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -83,10 +100,10 @@ jobs:
|
||||
- name: Install Composer dependencies
|
||||
uses: ramsey/composer-install@v2
|
||||
|
||||
- name: Use Node.js 20
|
||||
- name: Use Node.js 24
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 24
|
||||
|
||||
- name: Install
|
||||
run: npm install
|
||||
|
||||
8
.github/workflows/docker.yaml
vendored
8
.github/workflows/docker.yaml
vendored
@@ -61,10 +61,10 @@ jobs:
|
||||
- name: Install Composer dependencies
|
||||
uses: ramsey/composer-install@v2
|
||||
|
||||
- name: Use Node.js 20
|
||||
- name: Use Node.js 24
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 24
|
||||
|
||||
- name: Install
|
||||
run: npm install
|
||||
@@ -100,10 +100,10 @@ jobs:
|
||||
with:
|
||||
composer-options: --no-dev
|
||||
|
||||
- name: Use Node.js 20
|
||||
- name: Use Node.js 24
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 24
|
||||
|
||||
- name: Install
|
||||
run: npm install
|
||||
|
||||
96
.github/workflows/release.yaml
vendored
Normal file
96
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Build & Release
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
extensions: bcmath, curl, dom, gd, imagick, json, libxml, mbstring, pcntl, pdo, pdo_mysql, zip
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.4
|
||||
extensions: ${{ env.extensions }}
|
||||
tools: composer
|
||||
|
||||
- name: Install Composer dependencies
|
||||
run: composer install --no-dev --optimize-autoloader --no-interaction
|
||||
|
||||
- name: Use Node.js 24
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build frontend
|
||||
run: npm run build
|
||||
|
||||
- name: Prepare release directory
|
||||
run: |
|
||||
mkdir -p /tmp/InvoiceShelf/public
|
||||
|
||||
cp -r app /tmp/InvoiceShelf/
|
||||
cp -r bootstrap /tmp/InvoiceShelf/
|
||||
cp -r config /tmp/InvoiceShelf/
|
||||
cp -r database /tmp/InvoiceShelf/
|
||||
cp -r public/build /tmp/InvoiceShelf/public/
|
||||
cp -r public/favicons /tmp/InvoiceShelf/public/
|
||||
cp public/.htaccess /tmp/InvoiceShelf/public/
|
||||
cp public/index.php /tmp/InvoiceShelf/public/
|
||||
cp public/robots.txt /tmp/InvoiceShelf/public/
|
||||
cp public/web.config /tmp/InvoiceShelf/public/
|
||||
cp -r resources /tmp/InvoiceShelf/
|
||||
cp -r lang /tmp/InvoiceShelf/
|
||||
cp -r routes /tmp/InvoiceShelf/
|
||||
cp -r storage /tmp/InvoiceShelf/
|
||||
cp -r vendor /tmp/InvoiceShelf/ 2>/dev/null || true
|
||||
cp -r scripts /tmp/InvoiceShelf/
|
||||
cp version.md /tmp/InvoiceShelf/
|
||||
cp .env.example /tmp/InvoiceShelf/
|
||||
cp artisan /tmp/InvoiceShelf/
|
||||
cp composer.json /tmp/InvoiceShelf/
|
||||
cp composer.lock /tmp/InvoiceShelf/
|
||||
cp LICENSE /tmp/InvoiceShelf/
|
||||
cp readme.md /tmp/InvoiceShelf/
|
||||
cp SECURITY.md /tmp/InvoiceShelf/
|
||||
cp server.php /tmp/InvoiceShelf/
|
||||
|
||||
# Clean up runtime artifacts
|
||||
find /tmp/InvoiceShelf -wholename '*/[Tt]ests/*' -delete
|
||||
find /tmp/InvoiceShelf -wholename '*/[Tt]est/*' -delete
|
||||
rm -rf /tmp/InvoiceShelf/storage/framework/cache/data/* 2>/dev/null || true
|
||||
rm -f /tmp/InvoiceShelf/storage/framework/sessions/* 2>/dev/null || true
|
||||
rm -f /tmp/InvoiceShelf/storage/framework/views/* 2>/dev/null || true
|
||||
rm -f /tmp/InvoiceShelf/storage/logs/* 2>/dev/null || true
|
||||
touch /tmp/InvoiceShelf/storage/logs/laravel.log
|
||||
|
||||
- name: Generate manifest
|
||||
run: php scripts/generate-manifest.php /tmp/InvoiceShelf
|
||||
|
||||
- name: Create zip
|
||||
working-directory: /tmp
|
||||
run: zip -r InvoiceShelf.zip InvoiceShelf/
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: /tmp/InvoiceShelf.zip
|
||||
generate_release_notes: true
|
||||
make_latest: true
|
||||
1
.node-version
Normal file
1
.node-version
Normal file
@@ -0,0 +1 @@
|
||||
24
|
||||
5909
.phpstorm.meta.php
Normal file
5909
.phpstorm.meta.php
Normal file
File diff suppressed because it is too large
Load Diff
80
CLAUDE.md
Normal file
80
CLAUDE.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
InvoiceShelf is an open-source invoicing and expense tracking application built with Laravel 13 (PHP 8.4) and Vue 3. It supports multi-company tenancy, customer portals, recurring invoices, and PDF generation.
|
||||
|
||||
## Common Commands
|
||||
|
||||
### Development
|
||||
```bash
|
||||
composer run dev # Starts PHP server, queue listener, log tail, and Vite dev server concurrently
|
||||
npm run dev # Vite dev server only
|
||||
npm run build # Production frontend build
|
||||
```
|
||||
|
||||
### Testing
|
||||
```bash
|
||||
php artisan test --compact # Run all tests
|
||||
php artisan test --compact --filter=testName # Run specific test
|
||||
./vendor/bin/pest --stop-on-failure # Run via Pest directly
|
||||
make test # Makefile shortcut
|
||||
```
|
||||
|
||||
Tests use SQLite in-memory DB, configured in `phpunit.xml`. Tests seed via `DatabaseSeeder` + `DemoSeeder` in `beforeEach`. Authenticate with `Sanctum::actingAs()` and set the `company` header.
|
||||
|
||||
### Code Style
|
||||
```bash
|
||||
vendor/bin/pint --dirty --format agent # Fix style on modified PHP files
|
||||
vendor/bin/pint --test # Check style without fixing (CI uses this)
|
||||
```
|
||||
|
||||
### Artisan Generators
|
||||
Always use `php artisan make:*` with `--no-interaction` to create new files (models, controllers, migrations, tests, etc.).
|
||||
|
||||
## Architecture
|
||||
|
||||
### Multi-Tenancy
|
||||
Every major model has a `company_id` foreign key. The `CompanyMiddleware` sets the active company from the `company` request header. Bouncer authorization is scoped to the company level via `DefaultScope` (`app/Bouncer/Scopes/DefaultScope.php`).
|
||||
|
||||
### Authentication
|
||||
Three guards: `web` (session), `api` (Sanctum tokens for `/api/v1/`), `customer` (session for customer portal). API routes use `auth:sanctum` middleware; customer portal uses `auth:customer`.
|
||||
|
||||
### Routing
|
||||
- **API**: All endpoints under `/api/v1/` in `routes/api.php`, grouped with `auth:sanctum`, `company`, and `bouncer` middleware
|
||||
- **Web**: `routes/web.php` serves PDF endpoints, auth pages, and catch-all SPA routes (`/admin/{vue?}`, `/{company:slug}/customer/{vue?}`)
|
||||
|
||||
### Frontend
|
||||
- Entry point: `resources/scripts/main.js`
|
||||
- Vue Router: `resources/scripts/admin/admin-router.js` (admin), `resources/scripts/customer/customer-router.js` (customer portal)
|
||||
- State: Pinia stores in `resources/scripts/admin/stores/`
|
||||
- Path aliases: `@` = `resources/`, `$fonts`, `$images` for static assets
|
||||
- Vite dev server expects `invoiceshelf.test` hostname
|
||||
|
||||
### Backend Patterns
|
||||
- **Authorization**: Silber/Bouncer with policies in `app/Policies/`. Controllers use `$this->authorize()`.
|
||||
- **Validation**: Form Request classes, never inline validation
|
||||
- **API responses**: Eloquent API Resources in `app/Http/Resources/`
|
||||
- **PDF generation**: DomPDF (`GeneratesPdfTrait`) or Gotenberg
|
||||
- **Email**: Mailable classes with `EmailLog` tracking
|
||||
- **File storage**: Spatie MediaLibrary, supports local/S3/Dropbox
|
||||
- **Serial numbers**: `SerialNumberFormatter` service
|
||||
- **Company settings**: `CompanySetting` model (key-value per company)
|
||||
|
||||
### Database
|
||||
Supports MySQL, PostgreSQL, and SQLite. Prefer Eloquent over raw queries. Use `Model::query()` instead of `DB::`. Use eager loading to prevent N+1 queries.
|
||||
|
||||
## Code Conventions
|
||||
|
||||
- PHP: snake_case, constructor property promotion, explicit return types, PHPDoc blocks over inline comments
|
||||
- JS: camelCase
|
||||
- Always check sibling files for patterns before creating new ones
|
||||
- Use `config()` helper, never `env()` outside config files
|
||||
- Every change must have tests (feature tests preferred over unit tests)
|
||||
- Run `vendor/bin/pint --dirty --format agent` after modifying PHP files
|
||||
|
||||
## CI Pipeline
|
||||
|
||||
GitHub Actions (`check.yaml`): runs Pint style check, then builds frontend and runs Pest tests on PHP 8.4.
|
||||
2
Makefile
2
Makefile
@@ -29,6 +29,7 @@ dist-gen: clean composer npm-build
|
||||
@cp -r routes InvoiceShelf
|
||||
@cp -r storage InvoiceShelf
|
||||
@cp -r vendor InvoiceShelf 2> /dev/null || true
|
||||
@cp -r scripts InvoiceShelf
|
||||
@cp -r version.md InvoiceShelf
|
||||
@cp -r .env.example InvoiceShelf
|
||||
@cp -r artisan InvoiceShelf
|
||||
@@ -47,6 +48,7 @@ dist-clean: dist-gen
|
||||
@rm InvoiceShelf/storage/framework/sessions/* 2> /dev/null || true
|
||||
@rm InvoiceShelf/storage/framework/views/* 2> /dev/null || true
|
||||
@rm InvoiceShelf/storage/logs/* 2> /dev/null || true
|
||||
@php scripts/generate-manifest.php InvoiceShelf
|
||||
|
||||
dist: dist-clean
|
||||
@zip -r InvoiceShelf.zip InvoiceShelf
|
||||
|
||||
12337
_ide_helper.php
12337
_ide_helper.php
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,7 @@ class ResetApp extends Command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Clean database, database_created and public/storage folder';
|
||||
protected $description = 'Clean database and public/storage folder';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Console\Commands;
|
||||
|
||||
use App\Space\Updater;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
// Implementation taken from Akaunting - https://github.com/akaunting/akaunting
|
||||
class UpdateCommand extends Command
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
namespace App\Http\Controllers\V1\Admin\Backup;
|
||||
|
||||
use App\Jobs\CreateBackupJob;
|
||||
use App\Models\FileDisk;
|
||||
use App\Rules\Backup\PathToZip;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -27,6 +28,16 @@ class BackupsController extends ApiController
|
||||
$configuredBackupDisks = config('backup.backup.destination.disks');
|
||||
|
||||
try {
|
||||
if ($request->file_disk_id) {
|
||||
$fileDisk = FileDisk::find($request->file_disk_id);
|
||||
if ($fileDisk) {
|
||||
$fileDisk->setConfig();
|
||||
$prefix = env('DYNAMIC_DISK_PREFIX', 'temp_');
|
||||
config(['backup.backup.destination.disks' => [$prefix.$fileDisk->driver]]);
|
||||
$configuredBackupDisks = config('backup.backup.destination.disks');
|
||||
}
|
||||
}
|
||||
|
||||
$backupDestination = BackupDestination::create(config('filesystems.default'), config('backup.backup.name'));
|
||||
|
||||
$backups = Cache::remember("backups-{$request->file_disk_id}", now()->addSeconds(4), function () use ($backupDestination) {
|
||||
@@ -65,7 +76,10 @@ class BackupsController extends ApiController
|
||||
{
|
||||
$this->authorize('manage backups');
|
||||
|
||||
dispatch(new CreateBackupJob($request->all()))->onQueue(config('backup.queue.name'));
|
||||
$data = $request->all();
|
||||
$data['company'] = $request->header('company');
|
||||
|
||||
dispatch(new CreateBackupJob($data))->onQueue(config('backup.queue.name'));
|
||||
|
||||
return $this->respondSuccess();
|
||||
}
|
||||
|
||||
@@ -61,10 +61,10 @@ class CompaniesController extends Controller
|
||||
$company = Company::find($request->header('company'));
|
||||
$this->authorize('transfer company ownership', $company);
|
||||
|
||||
if ($user->hasCompany($company->id)) {
|
||||
if (! $user->hasCompany($company->id)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'User does not belongs to this company.',
|
||||
'message' => 'User does not belong to this company.',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,11 @@ class CustomersController extends Controller
|
||||
{
|
||||
$this->authorize('delete multiple customers');
|
||||
|
||||
Customer::deleteCustomers($request->ids);
|
||||
$ids = Customer::whereCompany()
|
||||
->whereIn('id', $request->ids)
|
||||
->pluck('id');
|
||||
|
||||
Customer::deleteCustomers($ids);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
|
||||
@@ -21,6 +21,7 @@ class CloneEstimateController extends Controller
|
||||
*/
|
||||
public function __invoke(Request $request, Estimate $estimate)
|
||||
{
|
||||
$this->authorize('view', $estimate);
|
||||
$this->authorize('create', Estimate::class);
|
||||
|
||||
$date = Carbon::now();
|
||||
|
||||
@@ -68,7 +68,11 @@ class EstimatesController extends Controller
|
||||
{
|
||||
$this->authorize('delete multiple estimates');
|
||||
|
||||
Estimate::destroy($request->ids);
|
||||
$ids = Estimate::whereCompany()
|
||||
->whereIn('id', $request->ids)
|
||||
->pluck('id');
|
||||
|
||||
Estimate::destroy($ids);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
|
||||
@@ -81,7 +81,11 @@ class ExpensesController extends Controller
|
||||
{
|
||||
$this->authorize('delete multiple expenses');
|
||||
|
||||
Expense::destroy($request->ids);
|
||||
$ids = Expense::whereCompany()
|
||||
->whereIn('id', $request->ids)
|
||||
->pluck('id');
|
||||
|
||||
Expense::destroy($ids);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
|
||||
@@ -25,7 +25,8 @@ class SearchController extends Controller
|
||||
->paginate(10);
|
||||
|
||||
if ($user->isOwner()) {
|
||||
$users = User::applyFilters($request->only(['search']))
|
||||
$users = User::whereCompany()
|
||||
->applyFilters($request->only(['search']))
|
||||
->latest()
|
||||
->paginate(10);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ class CloneInvoiceController extends Controller
|
||||
*/
|
||||
public function __invoke(Request $request, Invoice $invoice)
|
||||
{
|
||||
$this->authorize('view', $invoice);
|
||||
$this->authorize('create', Invoice::class);
|
||||
|
||||
$date = Carbon::now();
|
||||
|
||||
@@ -100,7 +100,11 @@ class InvoicesController extends Controller
|
||||
{
|
||||
$this->authorize('delete multiple invoices');
|
||||
|
||||
Invoice::deleteInvoices($request->ids);
|
||||
$ids = Invoice::whereCompany()
|
||||
->whereIn('id', $request->ids)
|
||||
->pluck('id');
|
||||
|
||||
Invoice::deleteInvoices($ids);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
|
||||
@@ -90,7 +90,11 @@ class ItemsController extends Controller
|
||||
{
|
||||
$this->authorize('delete multiple items');
|
||||
|
||||
Item::destroy($request->ids);
|
||||
$ids = Item::whereCompany()
|
||||
->whereIn('id', $request->ids)
|
||||
->pluck('id');
|
||||
|
||||
Item::destroy($ids);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
|
||||
@@ -73,7 +73,11 @@ class PaymentsController extends Controller
|
||||
{
|
||||
$this->authorize('delete multiple payments');
|
||||
|
||||
Payment::deletePayments($request->ids);
|
||||
$ids = Payment::whereCompany()
|
||||
->whereIn('id', $request->ids)
|
||||
->pluck('id');
|
||||
|
||||
Payment::deletePayments($ids);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
|
||||
@@ -84,7 +84,11 @@ class RecurringInvoiceController extends Controller
|
||||
{
|
||||
$this->authorize('delete multiple recurring invoices');
|
||||
|
||||
RecurringInvoice::deleteRecurringInvoice($request->ids);
|
||||
$ids = RecurringInvoice::whereCompany()
|
||||
->whereIn('id', $request->ids)
|
||||
->pluck('id');
|
||||
|
||||
RecurringInvoice::deleteRecurringInvoice($ids);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
|
||||
@@ -7,11 +7,12 @@ use App\Models\Company;
|
||||
use App\Models\CompanySetting;
|
||||
use App\Models\Currency;
|
||||
use App\Models\Expense;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use PDF;
|
||||
|
||||
class ExpensesReportController extends Controller
|
||||
{
|
||||
@@ -19,7 +20,7 @@ class ExpensesReportController extends Controller
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @param string $hash
|
||||
* @return JsonResponse
|
||||
* @return View|Response
|
||||
*/
|
||||
public function __invoke(Request $request, $hash)
|
||||
{
|
||||
@@ -31,14 +32,26 @@ class ExpensesReportController extends Controller
|
||||
|
||||
App::setLocale($locale);
|
||||
|
||||
$expenseCategories = Expense::with('category')
|
||||
// Fetch individual expenses (filtered and ordered by date), then group by category
|
||||
$expenses = Expense::with('category')
|
||||
->whereCompanyId($company->id)
|
||||
->applyFilters($request->only(['from_date', 'to_date']))
|
||||
->expensesAttributes()
|
||||
->applyFilters($request->only(['from_date', 'to_date', 'expense_category_id']))
|
||||
->orderBy('expense_date', 'asc')
|
||||
->get();
|
||||
$totalAmount = 0;
|
||||
foreach ($expenseCategories as $category) {
|
||||
$totalAmount += $category->total_amount;
|
||||
|
||||
$totalAmount = $expenses->sum('base_amount');
|
||||
|
||||
$grouped = $expenses->groupBy(function ($item) {
|
||||
return $item->category ? $item->category->name : trans('expenses.uncategorized');
|
||||
});
|
||||
|
||||
$expenseGroups = collect();
|
||||
foreach ($grouped as $categoryName => $group) {
|
||||
$expenseGroups->push([
|
||||
'name' => $categoryName,
|
||||
'expenses' => $group,
|
||||
'total' => $group->sum('base_amount'),
|
||||
]);
|
||||
}
|
||||
|
||||
$dateFormat = CompanySetting::getSetting('carbon_date_format', $company->id);
|
||||
@@ -62,7 +75,7 @@ class ExpensesReportController extends Controller
|
||||
->get();
|
||||
|
||||
view()->share([
|
||||
'expenseCategories' => $expenseCategories,
|
||||
'expenseGroups' => $expenseGroups,
|
||||
'colorSettings' => $colorSettings,
|
||||
'totalExpense' => $totalAmount,
|
||||
'company' => $company,
|
||||
@@ -70,7 +83,7 @@ class ExpensesReportController extends Controller
|
||||
'to_date' => $to_date,
|
||||
'currency' => $currency,
|
||||
]);
|
||||
$pdf = PDF::loadView('app.pdf.reports.expenses');
|
||||
$pdf = Pdf::loadView('app.pdf.reports.expenses');
|
||||
|
||||
if ($request->has('preview')) {
|
||||
return view('app.pdf.reports.expenses');
|
||||
|
||||
@@ -165,11 +165,11 @@ class MailConfigurationController extends Controller
|
||||
switch ($driver) {
|
||||
case 'smtp':
|
||||
$MailData = array_merge($MailData, [
|
||||
'mail_host' => $mailSettings['mail_host'] ?? '',
|
||||
'mail_port' => $mailSettings['mail_port'] ?? '',
|
||||
'mail_username' => $mailSettings['mail_username'] ?? '',
|
||||
'mail_password' => $mailSettings['mail_password'] ?? '',
|
||||
'mail_encryption' => $mailSettings['mail_encryption'] ?? 'none',
|
||||
'mail_host' => $mailSettings['mail_host'] ?? config('mail.mailers.smtp.host', ''),
|
||||
'mail_port' => $mailSettings['mail_port'] ?? config('mail.mailers.smtp.port', ''),
|
||||
'mail_username' => $mailSettings['mail_username'] ?? config('mail.mailers.smtp.username', ''),
|
||||
'mail_password' => $mailSettings['mail_password'] ?? config('mail.mailers.smtp.password', ''),
|
||||
'mail_encryption' => $mailSettings['mail_encryption'] ?? config('mail.mailers.smtp.encryption', 'none'),
|
||||
'mail_scheme' => $mailSettings['mail_scheme'] ?? '',
|
||||
'mail_url' => $mailSettings['mail_url'] ?? '',
|
||||
'mail_timeout' => $mailSettings['mail_timeout'] ?? '',
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\V1\Admin\Update;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Space\Updater;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class CleanFilesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* Removes any file that does not appear in the release manifest.json,
|
||||
* replacing the legacy hardcoded deleted_files list. Falls back to the
|
||||
* legacy deleteFiles() behaviour when the request still ships a
|
||||
* deleted_files payload (backward compatibility for older release
|
||||
* packages built before the manifest was introduced).
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
if ((! $request->user()) || (! $request->user()->isOwner())) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'You are not allowed to update this app.',
|
||||
], 401);
|
||||
}
|
||||
|
||||
// Backward compatibility: a release package built before the manifest
|
||||
// was introduced may still ship a deleted_files list. Honour it.
|
||||
if (isset($request->deleted_files) && ! empty($request->deleted_files)) {
|
||||
Updater::deleteFiles($request->deleted_files);
|
||||
}
|
||||
|
||||
$result = Updater::cleanStaleFiles();
|
||||
|
||||
return response()->json($result);
|
||||
}
|
||||
}
|
||||
@@ -25,14 +25,15 @@ class UsersController extends Controller
|
||||
|
||||
$user = $request->user();
|
||||
|
||||
$users = User::applyFilters($request->all())
|
||||
$users = User::whereCompany()
|
||||
->applyFilters($request->all())
|
||||
->where('id', '<>', $user->id)
|
||||
->latest()
|
||||
->paginate($limit);
|
||||
|
||||
return UserResource::collection($users)
|
||||
->additional(['meta' => [
|
||||
'user_total_count' => User::count(),
|
||||
'user_total_count' => User::whereCompany()->count(),
|
||||
]]);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,8 +48,9 @@ class DatabaseConfigurationController extends Controller
|
||||
public function getDatabaseEnvironment(Request $request)
|
||||
{
|
||||
$databaseData = [];
|
||||
$connection = $request->connection ?? config('database.default');
|
||||
|
||||
switch ($request->connection) {
|
||||
switch ($connection) {
|
||||
case 'sqlite':
|
||||
$databaseData = [
|
||||
'database_connection' => 'sqlite',
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace App\Http\Controllers\V1\Installation;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Space\InstallUtils;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -16,10 +15,6 @@ class FinishController extends Controller
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
if (! InstallUtils::createDbMarker()) {
|
||||
\Log::error('Install: Unable to create db marker.');
|
||||
}
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class OnboardingWizardController extends Controller
|
||||
*/
|
||||
public function getStep(Request $request)
|
||||
{
|
||||
if (! InstallUtils::dbMarkerExists()) {
|
||||
if (! InstallUtils::isDbCreated()) {
|
||||
return response()->json([
|
||||
'profile_complete' => 0,
|
||||
'profile_language' => 'en',
|
||||
|
||||
@@ -17,7 +17,11 @@ class InstallationMiddleware
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
if (! InstallUtils::isDbCreated() || Setting::getSetting('profile_complete') !== 'COMPLETED') {
|
||||
try {
|
||||
if (! InstallUtils::isDbCreated() || Setting::getSetting('profile_complete') !== 'COMPLETED') {
|
||||
return redirect('/installation');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return redirect('/installation');
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,13 @@ class RedirectIfInstalled
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
if (InstallUtils::dbMarkerExists()) {
|
||||
if (Setting::getSetting('profile_complete') === 'COMPLETED') {
|
||||
return redirect('login');
|
||||
if (InstallUtils::isDbCreated()) {
|
||||
try {
|
||||
if (Setting::getSetting('profile_complete') === 'COMPLETED') {
|
||||
return redirect('login');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// Settings table may not exist yet during installation
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\FileDisk;
|
||||
use App\Space\BackupConfigurationFactory;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Spatie\Backup\Config\Config;
|
||||
use Spatie\Backup\Tasks\Backup\BackupJobFactory;
|
||||
|
||||
class CreateBackupJob implements ShouldQueue
|
||||
@@ -25,7 +24,7 @@ class CreateBackupJob implements ShouldQueue
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($data = '')
|
||||
public function __construct($data = [])
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
@@ -35,14 +34,7 @@ class CreateBackupJob implements ShouldQueue
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$fileDisk = FileDisk::find($this->data['file_disk_id']);
|
||||
$fileDisk->setConfig();
|
||||
|
||||
$prefix = env('DYNAMIC_DISK_PREFIX', 'temp_');
|
||||
|
||||
config(['backup.backup.destination.disks' => [$prefix.$fileDisk->driver]]);
|
||||
|
||||
$config = Config::fromArray(config('backup'));
|
||||
$config = BackupConfigurationFactory::make($this->data);
|
||||
$backupJob = BackupJobFactory::createFromConfig($config);
|
||||
if (! defined('SIGINT')) {
|
||||
$backupJob->disableSignals();
|
||||
|
||||
@@ -213,6 +213,13 @@ class User extends Authenticatable implements HasMedia
|
||||
return $query->where('email', 'LIKE', '%'.$email.'%');
|
||||
}
|
||||
|
||||
public function scopeWhereCompany($query)
|
||||
{
|
||||
return $query->whereHas('companies', function ($q) {
|
||||
$q->where('company_id', request()->header('company'));
|
||||
});
|
||||
}
|
||||
|
||||
public function scopePaginateData($query, $limit)
|
||||
{
|
||||
if ($limit == 'all') {
|
||||
|
||||
@@ -32,7 +32,7 @@ class CustomerPolicy
|
||||
*/
|
||||
public function view(User $user, Customer $customer): bool
|
||||
{
|
||||
if (BouncerFacade::can('view-customer', $customer)) {
|
||||
if (BouncerFacade::can('view-customer', $customer) && $user->hasCompany($customer->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class CustomerPolicy
|
||||
*/
|
||||
public function update(User $user, Customer $customer): bool
|
||||
{
|
||||
if (BouncerFacade::can('edit-customer', $customer)) {
|
||||
if (BouncerFacade::can('edit-customer', $customer) && $user->hasCompany($customer->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ class CustomerPolicy
|
||||
*/
|
||||
public function delete(User $user, Customer $customer): bool
|
||||
{
|
||||
if (BouncerFacade::can('delete-customer', $customer)) {
|
||||
if (BouncerFacade::can('delete-customer', $customer) && $user->hasCompany($customer->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ class CustomerPolicy
|
||||
*/
|
||||
public function restore(User $user, Customer $customer): bool
|
||||
{
|
||||
if (BouncerFacade::can('delete-customer', $customer)) {
|
||||
if (BouncerFacade::can('delete-customer', $customer) && $user->hasCompany($customer->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ class CustomerPolicy
|
||||
*/
|
||||
public function forceDelete(User $user, Customer $customer): bool
|
||||
{
|
||||
if (BouncerFacade::can('delete-customer', $customer)) {
|
||||
if (BouncerFacade::can('delete-customer', $customer) && $user->hasCompany($customer->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
40
app/Space/BackupConfigurationFactory.php
Normal file
40
app/Space/BackupConfigurationFactory.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Space;
|
||||
|
||||
use App\Models\CompanySetting;
|
||||
use App\Models\FileDisk;
|
||||
use Exception;
|
||||
use Spatie\Backup\Config\Config;
|
||||
|
||||
class BackupConfigurationFactory
|
||||
{
|
||||
public static function make($data = []): Config
|
||||
{
|
||||
if (blank($data['company'] ?? null)) {
|
||||
throw new Exception('The Company ID is missig');
|
||||
}
|
||||
|
||||
if (blank($data['file_disk_id'] ?? null)) {
|
||||
throw new Exception('No file disk selected');
|
||||
}
|
||||
|
||||
$fileDisk = FileDisk::find($data['file_disk_id']);
|
||||
|
||||
$fileDisk->setConfig();
|
||||
|
||||
$prefix = env('DYNAMIC_DISK_PREFIX', 'temp_');
|
||||
|
||||
config(['backup.backup.destination.disks' => [$prefix.$fileDisk->driver]]);
|
||||
|
||||
$companyNotificationEmail = CompanySetting::getSetting('notification_email', $data['company']);
|
||||
|
||||
if ($companyNotificationEmail) {
|
||||
config(['backup.notifications.mail.to' => $companyNotificationEmail]);
|
||||
}
|
||||
|
||||
$config = Config::fromArray(config('backup'));
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,6 @@ namespace App\Space;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use League\Flysystem\FilesystemException;
|
||||
|
||||
class InstallUtils
|
||||
{
|
||||
@@ -17,7 +15,7 @@ class InstallUtils
|
||||
*/
|
||||
public static function isDbCreated()
|
||||
{
|
||||
return self::dbMarkerExists() && self::tableExists('users');
|
||||
return self::tableExists('users');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,54 +42,6 @@ class InstallUtils
|
||||
return $cache[$table];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if database created marker exists
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function dbMarkerExists()
|
||||
{
|
||||
try {
|
||||
return \Storage::disk('local')->has('database_created');
|
||||
} catch (FilesystemException $e) {
|
||||
Log::error('Unable to verify db marker: '.$e->getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the database marker
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function createDbMarker()
|
||||
{
|
||||
try {
|
||||
return \Storage::disk('local')->put('database_created', time());
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Unable to create db marker: '.$e->getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the database marker
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function deleteDbMarker()
|
||||
{
|
||||
try {
|
||||
return \Storage::disk('local')->delete('database_created');
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Unable to delete db marker: '.$e->getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the app version
|
||||
*
|
||||
|
||||
@@ -130,6 +130,80 @@ class Updater
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function cleanStaleFiles(): array
|
||||
{
|
||||
$manifestPath = base_path('manifest.json');
|
||||
|
||||
if (! File::exists($manifestPath)) {
|
||||
return ['success' => true, 'cleaned' => 0];
|
||||
}
|
||||
|
||||
$manifest = json_decode(File::get($manifestPath), true);
|
||||
|
||||
if (! is_array($manifest)) {
|
||||
return ['success' => false, 'error' => 'Invalid manifest'];
|
||||
}
|
||||
|
||||
$manifestLookup = array_flip($manifest);
|
||||
$protectedPaths = config('invoiceshelf.update_protected_paths', []);
|
||||
$cleaned = 0;
|
||||
|
||||
$iterator = new \RecursiveIteratorIterator(
|
||||
new \RecursiveDirectoryIterator(base_path(), \RecursiveDirectoryIterator::SKIP_DOTS),
|
||||
\RecursiveIteratorIterator::CHILD_FIRST
|
||||
);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
$relativePath = substr($file->getPathname(), strlen(base_path()) + 1);
|
||||
|
||||
if (static::isProtectedPath($relativePath, $protectedPaths)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($file->isFile() && ! isset($manifestLookup[$relativePath])) {
|
||||
File::delete($file->getPathname());
|
||||
$cleaned++;
|
||||
}
|
||||
}
|
||||
|
||||
// Second pass: remove empty directories
|
||||
$dirIterator = new \RecursiveIteratorIterator(
|
||||
new \RecursiveDirectoryIterator(base_path(), \RecursiveDirectoryIterator::SKIP_DOTS),
|
||||
\RecursiveIteratorIterator::CHILD_FIRST
|
||||
);
|
||||
|
||||
foreach ($dirIterator as $item) {
|
||||
if (! $item->isDir()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$relativePath = substr($item->getPathname(), strlen(base_path()) + 1);
|
||||
|
||||
if (static::isProtectedPath($relativePath, $protectedPaths)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$entries = scandir($item->getPathname());
|
||||
|
||||
if (count($entries) <= 2) {
|
||||
@rmdir($item->getPathname());
|
||||
}
|
||||
}
|
||||
|
||||
return ['success' => true, 'cleaned' => $cleaned];
|
||||
}
|
||||
|
||||
private static function isProtectedPath(string $relativePath, array $protectedPaths): bool
|
||||
{
|
||||
foreach ($protectedPaths as $protected) {
|
||||
if ($relativePath === $protected || str_starts_with($relativePath, $protected.'/')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function migrateUpdate()
|
||||
{
|
||||
Artisan::call('migrate --force');
|
||||
|
||||
@@ -19,6 +19,9 @@ final class PdfHtmlSanitizer
|
||||
return '';
|
||||
}
|
||||
|
||||
// Legacy/invalid `</br>` is dropped by libxml and collapses lines in PDF output; normalize to `<br />`.
|
||||
$html = str_replace('</br>', '<br />', $html);
|
||||
|
||||
$allowedTags = '<br><br/><p><b><strong><i><em><u><ol><ul><li><table><tr><td><th><thead><tbody><tfoot><h1><h2><h3><h4><blockquote>';
|
||||
$html = strip_tags($html, $allowedTags);
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ trait GeneratesPdfTrait
|
||||
|
||||
$str = str_replace('<p>', '', $str);
|
||||
|
||||
$str = str_replace('</p>', '</br>', $str);
|
||||
$str = str_replace('</p>', '<br />', $str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
@@ -9,15 +9,12 @@
|
||||
"type": "project",
|
||||
"require": {
|
||||
"php": "^8.4",
|
||||
"aws/aws-sdk-php": "^3.336",
|
||||
"barryvdh/laravel-dompdf": "^v3.0",
|
||||
"doctrine/dbal": "^4.2",
|
||||
"dragonmantank/cron-expression": "^v3.4",
|
||||
"gotenberg/gotenberg-php": "^2.8",
|
||||
"guzzlehttp/guzzle": "^7.9",
|
||||
"hashids/hashids": "^5.0",
|
||||
"invoiceshelf/modules": "^1.0.0",
|
||||
"jasonmccreary/laravel-test-assertions": "^v2.4",
|
||||
"laravel/framework": "^13.0",
|
||||
"laravel/helpers": "^1.7",
|
||||
"laravel/sanctum": "^4.0",
|
||||
@@ -36,6 +33,7 @@
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-ide-helper": "^3.5",
|
||||
"fakerphp/faker": "^1.23",
|
||||
"jasonmccreary/laravel-test-assertions": "^2.9",
|
||||
"laravel/boost": "^2.3",
|
||||
"laravel/pint": "^1.13",
|
||||
"laravel/sail": "^1.41",
|
||||
@@ -83,7 +81,11 @@
|
||||
"dev": [
|
||||
"Composer\\Config::disableProcessTimeout",
|
||||
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite"
|
||||
]
|
||||
],
|
||||
"ide-helper": [
|
||||
"@php artisan ide-helper:generate",
|
||||
"@php artisan ide-helper:meta"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
|
||||
3915
composer.lock
generated
3915
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,15 @@ return [
|
||||
'report' => false,
|
||||
],
|
||||
|
||||
'public' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app/public'),
|
||||
'url' => env('APP_URL').'/storage',
|
||||
'visibility' => 'public',
|
||||
'throw' => false,
|
||||
'report' => false,
|
||||
],
|
||||
|
||||
's3' => [
|
||||
'driver' => 's3',
|
||||
'key' => env('AWS_KEY'),
|
||||
|
||||
@@ -16,7 +16,7 @@ return [
|
||||
/*
|
||||
* Minimum php version.
|
||||
*/
|
||||
'min_php_version' => '8.2.0',
|
||||
'min_php_version' => '8.4.0',
|
||||
|
||||
/*
|
||||
* Minimum mysql version.
|
||||
@@ -47,6 +47,25 @@ return [
|
||||
*/
|
||||
'base_url' => 'https://invoiceshelf.com',
|
||||
|
||||
/*
|
||||
* Paths protected from cleanup during updates.
|
||||
* The updater will never delete files under these prefixes.
|
||||
*/
|
||||
'update_protected_paths' => [
|
||||
'.env',
|
||||
'storage',
|
||||
'vendor',
|
||||
'node_modules',
|
||||
'Modules',
|
||||
'public/storage',
|
||||
'.git',
|
||||
'bootstrap/cache',
|
||||
'manifest.json',
|
||||
'android',
|
||||
'ios',
|
||||
'mobile',
|
||||
],
|
||||
|
||||
/*
|
||||
* List of languages supported by InvoiceShelf.
|
||||
*/
|
||||
|
||||
@@ -8,7 +8,6 @@ use App\Models\CompanySetting;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use App\Space\InstallUtils;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Silber\Bouncer\BouncerFacade;
|
||||
|
||||
@@ -71,8 +70,5 @@ class DemoSeeder extends Seeder
|
||||
|
||||
// Mark profile setup as complete
|
||||
Setting::setSetting('profile_complete', 'COMPLETED');
|
||||
|
||||
// Create installation marker
|
||||
InstallUtils::createDbMarker();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
FROM --platform=$BUILDPLATFORM node AS static_builder
|
||||
FROM --platform=$BUILDPLATFORM node:24 AS static_builder
|
||||
WORKDIR /var/www/html
|
||||
COPY . /var/www/html
|
||||
RUN yarn && yarn build
|
||||
|
||||
FROM serversideup/php:8.4-fpm-alpine AS base
|
||||
USER root
|
||||
RUN apk add --no-cache sqlite
|
||||
RUN apk add --no-cache bash nano mariadb-client postgresql-client sqlite
|
||||
RUN install-php-extensions exif
|
||||
RUN install-php-extensions pgsql
|
||||
RUN install-php-extensions sqlite3
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
FROM --platform=$BUILDPLATFORM node:20 AS static_builder
|
||||
FROM --platform=$BUILDPLATFORM node:24 AS static_builder
|
||||
WORKDIR /var/www/html
|
||||
COPY . /var/www/html
|
||||
RUN yarn && yarn build
|
||||
|
||||
FROM serversideup/php:8.4-fpm-nginx-alpine AS base
|
||||
USER root
|
||||
RUN apk add --no-cache bash nano
|
||||
RUN apk add --no-cache bash nano mariadb-client postgresql-client sqlite
|
||||
RUN install-php-extensions exif
|
||||
RUN install-php-extensions pgsql
|
||||
RUN install-php-extensions sqlite3
|
||||
@@ -19,6 +19,10 @@ FROM serversideup/php:8.4-fpm-nginx-alpine AS base
|
||||
RUN install-php-extensions intl
|
||||
RUN install-php-extensions curl
|
||||
|
||||
# Copy entrypoint and inject script, and make sure they are executable
|
||||
COPY --chmod=755 docker/production/inject.sh /inject.sh
|
||||
COPY --chmod=755 docker/production/entrypoint.d/ /etc/entrypoint.d/
|
||||
|
||||
FROM base AS production
|
||||
ENV AUTORUN_ENABLED=true
|
||||
ENV PHP_OPCACHE_ENABLE=1
|
||||
@@ -36,7 +40,3 @@ FROM base AS production
|
||||
COPY --from=static_builder --chown=www-data:www-data /var/www/html/public /var/www/html/public
|
||||
COPY --chown=www-data:www-data . /var/www/html
|
||||
RUN composer install --prefer-dist --no-dev --optimize-autoloader
|
||||
|
||||
# Copy entrypoint and inject script, and make sure they are executable
|
||||
COPY --chmod=755 docker/production/inject.sh /inject.sh
|
||||
COPY --chmod=755 docker/production/entrypoint.d/ /etc/entrypoint.d/
|
||||
|
||||
@@ -33,8 +33,15 @@ if [ "$DB_CONNECTION" = "sqlite" ] || [ -z "$DB_CONNECTION" ]; then
|
||||
chown www-data:www-data "$DB_DATABASE"
|
||||
fi
|
||||
|
||||
echo "**** Setting up artisan permissions ****"
|
||||
echo "**** Setting up folder permissions ****"
|
||||
chmod +x artisan
|
||||
chown -R www-data:www-data storage bootstrap/cache
|
||||
chmod -R 775 storage bootstrap/cache
|
||||
|
||||
if [ ! -L /var/www/html/public/storage ]; then
|
||||
echo "**** Creating storage symlink (public/storage) ****"
|
||||
./artisan storage:link --force -n || true
|
||||
fi
|
||||
|
||||
if ! grep -q "APP_KEY" /var/www/html/.env
|
||||
then
|
||||
|
||||
13
eslint.config.mjs
Normal file
13
eslint.config.mjs
Normal file
@@ -0,0 +1,13 @@
|
||||
import pluginVue from 'eslint-plugin-vue'
|
||||
import eslintConfigPrettier from 'eslint-config-prettier'
|
||||
|
||||
export default [
|
||||
...pluginVue.configs['flat/recommended'],
|
||||
eslintConfigPrettier,
|
||||
{
|
||||
files: ['resources/scripts/**/*.{js,vue}'],
|
||||
rules: {
|
||||
'vue/no-mutating-props': 'off',
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "تحديث التشطيب",
|
||||
"update_failed": "فشل التحديث",
|
||||
"update_failed_text": "آسف! فشل التحديث الخاص بك في: {step} خطوة",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "النسخ الاحتياطي | النسخ الاحتياطية",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Dokončování aktualizace",
|
||||
"update_failed": "Aktualizace se nezdařila",
|
||||
"update_failed_text": "Omlouváme se! Aktualizace se nezdařila v {step}. kroku",
|
||||
"update_warning": "Všechny soubory aplikace a výchozí soubory šablon budou přepsány při aktualizaci aplikace pomocí tohoto nástroje. Před aktualizací si prosím zálohujte šablony a databázi."
|
||||
"update_warning": "Všechny soubory aplikace a výchozí soubory šablon budou přepsány při aktualizaci aplikace pomocí tohoto nástroje. Před aktualizací si prosím zálohujte šablony a databázi.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Záloha | Zálohy",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Update beenden",
|
||||
"update_failed": "Update fehlgeschlagen",
|
||||
"update_failed_text": "Es tut uns leid! Ihr Update ist am folgenden Schritt fehlgeschlagen: {step}",
|
||||
"update_warning": "Alle Anwendungsdateien und Standardvorlagen werden überschrieben, wenn Sie die Anwendung mit diesem Hilfsprogramm aktualisieren. Bitte machen Sie vor dem Update ein Backup Ihrer Vorlagen & Datenbank."
|
||||
"update_warning": "Alle Anwendungsdateien und Standardvorlagen werden überschrieben, wenn Sie die Anwendung mit diesem Hilfsprogramm aktualisieren. Bitte machen Sie vor dem Update ein Backup Ihrer Vorlagen & Datenbank.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Sicherung | Sicherungen",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Ολοκλήρωση Ενημέρωσης",
|
||||
"update_failed": "Αποτυχία ενημέρωσης",
|
||||
"update_failed_text": "Συγνώμη! Η ενημέρωσή σας απέτυχε σε: {step} βήμα",
|
||||
"update_warning": "Όλα τα αρχεία εφαρμογών και τα προεπιλεγμένα αρχεία προτύπων θα αντικατασταθούν όταν ενημερώνετε την εφαρμογή χρησιμοποιώντας αυτό το βοηθητικό πρόγραμμα. Παρακαλώ πάρτε ένα αντίγραφο ασφαλείας των προτύπων και της βάσης δεδομένων σας πριν από την ενημέρωση."
|
||||
"update_warning": "Όλα τα αρχεία εφαρμογών και τα προεπιλεγμένα αρχεία προτύπων θα αντικατασταθούν όταν ενημερώνετε την εφαρμογή χρησιμοποιώντας αυτό το βοηθητικό πρόγραμμα. Παρακαλώ πάρτε ένα αντίγραφο ασφαλείας των προτύπων και της βάσης δεδομένων σας πριν από την ενημέρωση.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Αντίγραφο Ασφαλείας \"Αντίγραφα Ασφαλείας",
|
||||
|
||||
@@ -652,6 +652,7 @@
|
||||
"currency": "Currency",
|
||||
"contact": "Contact",
|
||||
"category": "Category",
|
||||
"uncategorized": "Uncategorized",
|
||||
"from_date": "From Date",
|
||||
"to_date": "To Date",
|
||||
"expense_date": "Date",
|
||||
@@ -1322,11 +1323,13 @@
|
||||
"unzipping_package": "Unzipping Package",
|
||||
"copying_files": "Copying Files",
|
||||
"deleting_files": "Deleting Unused files",
|
||||
"cleaning_stale_files": "Cleaning stale files",
|
||||
"running_migrations": "Running Migrations",
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
@@ -1648,6 +1651,7 @@
|
||||
"pdf_total_tax_label": "TOTAL TAX",
|
||||
"pdf_tax_types_label": "Tax Types",
|
||||
"pdf_expenses_label": "Expenses",
|
||||
"pdf_expense_group_total_label": "Group total:",
|
||||
"pdf_bill_to": "Bill to,",
|
||||
"pdf_ship_to": "Ship to,",
|
||||
"pdf_received_from": "Received from:",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Actualización final",
|
||||
"update_failed": "Actualización fallida",
|
||||
"update_failed_text": "¡Lo siento! Su actualización falló el: {step} paso",
|
||||
"update_warning": "Todos los archivos y temas predeterminados se sobreescribirán cuando actualice la aplicación a través de esta utilidad. Por favor, cree una copia de seguridad de sus temas y base de datos antes de actualizar."
|
||||
"update_warning": "Todos los archivos y temas predeterminados se sobreescribirán cuando actualice la aplicación a través de esta utilidad. Por favor, cree una copia de seguridad de sus temas y base de datos antes de actualizar.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Copia de seguridad | Copias de seguridad",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Lopetetaan päivitys",
|
||||
"update_failed": "Päivitys epäonnistui",
|
||||
"update_failed_text": "Sorry! Päivityksesi epäonnistui : {step} vaiheessa",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Varmuuskopio | Varmuuskopiot",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finalisation de la mise à jour",
|
||||
"update_failed": "Échec de la mise à jour",
|
||||
"update_failed_text": "Désolé ! Votre mise à jour a échoué à: {step} étape",
|
||||
"update_warning": "Cet utilitaire va écraser tous les fichiers et templates de l'application. Veuillez faire une sauvegarde de vos templates et de la base de donnée avant de faire la mise à jour."
|
||||
"update_warning": "Cet utilitaire va écraser tous les fichiers et templates de l'application. Veuillez faire une sauvegarde de vos templates et de la base de donnée avant de faire la mise à jour.",
|
||||
"requirements_not_met": "La mise à jour ne peut pas continuer car certaines exigences système ne sont pas respectées (y compris la version PHP minimale). Veuillez corriger les exigences en échec puis réessayer."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Sauvegarde | Sauvegardes",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"yes": "हां",
|
||||
"no": "नहीं",
|
||||
"sort_by": "इसके अनुसार क्रमबद्ध करें",
|
||||
"ascending": "आरोही",
|
||||
"ascending": "बढ़ते क्रम में",
|
||||
"descending": "उतरते",
|
||||
"subject": "विषय",
|
||||
"body": "बॉडी",
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Završavanje ažuriranja",
|
||||
"update_failed": "Neuspešno ažuriranje",
|
||||
"update_failed_text": "Žao mi je! Tvoje ažuriranje nije uspelo na koraku broj: {step} korak",
|
||||
"update_warning": "Svi dokumenti i predlošci programa će biti obrisani korištenjem ove funkcije. Molimo napravite sigurnosnu kopiju svojih predložaka i baze podataka prije ažuriranja."
|
||||
"update_warning": "Svi dokumenti i predlošci programa će biti obrisani korištenjem ove funkcije. Molimo napravite sigurnosnu kopiju svojih predložaka i baze podataka prije ažuriranja.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Sigurnosna kopija | Sigurnosne kopije",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Menyelesaikan Pembaruan",
|
||||
"update_failed": "Pembaruan Gagal",
|
||||
"update_failed_text": "Maaf! Pembaruan Anda gagal pada langkah : {step}",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Aggiornamento di finitura",
|
||||
"update_failed": "Aggiornamento non riuscito",
|
||||
"update_failed_text": "Scusate! L'aggiornamento non è riuscito il: passaggio {step}",
|
||||
"update_warning": "Tutti i file dell'applicazione e i file dei modelli predefiniti verranno sovrascritti quando si aggiorna l'applicazione tramite questa utility. Si prega di eseguire un backup dei modelli e del database prima di effettuare l'aggiornamento."
|
||||
"update_warning": "Tutti i file dell'applicazione e i file dei modelli predefiniti verranno sovrascritti quando si aggiorna l'applicazione tramite questa utility. Si prega di eseguire un backup dei modelli e del database prima di effettuare l'aggiornamento.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "アップデート完了",
|
||||
"update_failed": "アップデートに失敗しました",
|
||||
"update_failed_text": "申し訳ありません。更新に失敗しました: {step} ステップ",
|
||||
"update_warning": "このユーティリティを使用してアプリケーションを更新するとすべてのアプリケーションファイルと既定のテンプレートファイルが上書きされます。更新する前にテンプレートとデータベースのバックアップを作成してください。"
|
||||
"update_warning": "このユーティリティを使用してアプリケーションを更新するとすべてのアプリケーションファイルと既定のテンプレートファイルが上書きされます。更新する前にテンプレートとデータベースのバックアップを作成してください。",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "バックアップ | バックアップ",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Pabeidz atjauninājumu",
|
||||
"update_failed": "Atjaunināšana neizdevās",
|
||||
"update_failed_text": "Atvainojiet! Jūsu atjauninājuma laikā notika kļūda: {step}. solī",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Afwerking Update",
|
||||
"update_failed": "Update mislukt",
|
||||
"update_failed_text": "Sorry! Je update is mislukt op: {step} step ",
|
||||
"update_warning": "Alle applicatiebestanden en de standaard sjabloonbestanden worden overschreven wanneer u de applicatie aan de hand van dit hulpprogramma bijwerkt. Maak een reservekopie van uw sjabloonbestanden en databank voordat u verder gaat."
|
||||
"update_warning": "Alle applicatiebestanden en de standaard sjabloonbestanden worden overschreven wanneer u de applicatie aan de hand van dit hulpprogramma bijwerkt. Maak een reservekopie van uw sjabloonbestanden en databank voordat u verder gaat.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Kończenie aktualizacji",
|
||||
"update_failed": "Aktualizacja nie powiodła się",
|
||||
"update_failed_text": "Przepraszamy! Twoja aktualizacja nie powiodła się w kroku: {step}",
|
||||
"update_warning": "Wszystkie pliki aplikacji i domyślne pliki szablonu zostaną nadpisane podczas aktualizacji aplikacji przy użyciu tego narzędzia. Przed aktualizacją wykonaj kopię zapasową szablonów i bazy danych."
|
||||
"update_warning": "Wszystkie pliki aplikacji i domyślne pliki szablonu zostaną nadpisane podczas aktualizacji aplikacji przy użyciu tego narzędzia. Przed aktualizacją wykonaj kopię zapasową szablonów i bazy danych.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Kopia zapasowa | Kopie zapasowe",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Atualização de acabamento",
|
||||
"update_failed": "Atualização falhou",
|
||||
"update_failed_text": "Desculpa! Sua atualização falhou em: {step} step",
|
||||
"update_warning": "Todos os arquivos do aplicativo e modelos padrão serão sobrescritos ao atualizar o aplicativo usando esta ferramenta. Faça backup de seus modelos e banco de dados antes de atualizar."
|
||||
"update_warning": "Todos os arquivos do aplicativo e modelos padrão serão sobrescritos ao atualizar o aplicativo usando esta ferramenta. Faça backup de seus modelos e banco de dados antes de atualizar.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Acabando a Atualização",
|
||||
"update_failed": "Atualização falhou",
|
||||
"update_failed_text": "Desculpa! Sua atualização falhou no passo: {step}",
|
||||
"update_warning": "Todos os arquivos do aplicativo e modelos padrão serão sobrescritos ao atualizar o aplicativo usando esta ferramenta. Faça backup de seus modelos e banco de dados antes de atualizar."
|
||||
"update_warning": "Todos os arquivos do aplicativo e modelos padrão serão sobrescritos ao atualizar o aplicativo usando esta ferramenta. Faça backup de seus modelos e banco de dados antes de atualizar.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Заканчиваем обновление",
|
||||
"update_failed": "Не удалось обновить",
|
||||
"update_failed_text": "Извиняюсь! Ваше обновление не выполнено на шаге {step}",
|
||||
"update_warning": "Все файлы приложения и файлы шаблонов по умолчанию будут перезаписаны при обновлении приложения с помощью этой утилиты. Перед обновлением сделайте резервную копию ваших шаблонов и базы данных."
|
||||
"update_warning": "Все файлы приложения и файлы шаблонов по умолчанию будут перезаписаны при обновлении приложения с помощью этой утилиты. Перед обновлением сделайте резервную копию ваших шаблонов и базы данных.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Резервное копирование | Резервные копии",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Ukončovanie Aktualizácie",
|
||||
"update_failed": "Aktualizácia zlyhala!",
|
||||
"update_failed_text": "Aktualizácia zlyhala na : {step} kroku",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Záloha | Zálohy",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Posodobitev dodelave",
|
||||
"update_failed": "Posodobitev ni uspela",
|
||||
"update_failed_text": "Žal mi je! Posodobitev je bila neuspešna na : {step} koraku",
|
||||
"update_warning": "Ko posodobite aplikacijo s tem orodjem, se prepišejo vse datoteke aplikacije in privzete datoteke predlog. Pred posodabljanjem naredite varnostno kopijo predlog in zbirke podatkov."
|
||||
"update_warning": "Ko posodobite aplikacijo s tem orodjem, se prepišejo vse datoteke aplikacije in privzete datoteke predlog. Pred posodabljanjem naredite varnostno kopijo predlog in zbirke podatkov.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Varnostno kopiranje | Varnostne kopije",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Završavanje ažuriranja",
|
||||
"update_failed": "Neuspešno ažuriranje",
|
||||
"update_failed_text": "Žao mi je! Tvoje ažuriranje nije uspelo na koraku broj: {step} korak",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Bekap | Bekapi",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Avslutar uppdateringen",
|
||||
"update_failed": "Uppdatering misslyckades",
|
||||
"update_failed_text": "Uppdateringen misslyckades på steg : {step} step",
|
||||
"update_warning": "Alla programfiler och standard mallfiler kommer att skrivas över när du uppdaterar programmet med det här verktyget. Ta en säkerhetskopia av dina mallar & databas innan du uppdaterar."
|
||||
"update_warning": "Alla programfiler och standard mallfiler kommer att skrivas över när du uppdaterar programmet med det här verktyget. Ta en säkerhetskopia av dina mallar & databas innan du uppdaterar.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Säkerhetskopiering | Säkerhetskopieringar",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "การอัพเดตเสร็จแล้ว",
|
||||
"update_failed": "การอัพเดทล้มเหลว",
|
||||
"update_failed_text": "โทษที!การอัปเดตของคุณล้มเหลวใน: ขั้นตอน {step}",
|
||||
"update_warning": "ไฟล์แอปพลิเคชันและไฟล์แม่แบบเริ่มต้นทั้งหมดจะถูกเขียนทับเมื่อคุณอัปเดตแอปพลิเคชันโดยใช้ยูทิลิตีนี้โปรดใช้การสำรองข้อมูลของแม่แบบและฐานข้อมูลของคุณก่อนที่จะอัพเดต"
|
||||
"update_warning": "ไฟล์แอปพลิเคชันและไฟล์แม่แบบเริ่มต้นทั้งหมดจะถูกเขียนทับเมื่อคุณอัปเดตแอปพลิเคชันโดยใช้ยูทิลิตีนี้โปรดใช้การสำรองข้อมูลของแม่แบบและฐานข้อมูลของคุณก่อนที่จะอัพเดต",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "การสำรองข้อมูล | ข้อมูลสำรอง",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Güncelleme tamamlanıyor",
|
||||
"update_failed": "Güncelleştirme Başarısız",
|
||||
"update_failed_text": "Üzgünüz! Güncelleştirmeniz :{step} adımında başarısız oldu",
|
||||
"update_warning": "Uygulamayı bu araçla güncellediğinizde tüm uygulama dosyaları ve varsayılan şablon dosyaları üzerine yazılacaktır. Güncellemeden önce şablonlarınızın ve veritabanınızın yedeğini almayı unutmayın."
|
||||
"update_warning": "Uygulamayı bu araçla güncellediğinizde tüm uygulama dosyaları ve varsayılan şablon dosyaları üzerine yazılacaktır. Güncellemeden önce şablonlarınızın ve veritabanınızın yedeğini almayı unutmayın.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Yedek | Yedekler",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Оновлення завершення",
|
||||
"update_failed": "Спроба оновлення зазнала невдачі",
|
||||
"update_failed_text": "Вибачте! Оновлення не вдалось на кроці: {step} ",
|
||||
"update_warning": "Всі файли програми та файли шаблонів за замовчуванням будуть перезаписані, коли ви оновите програму за допомогою цієї утиліти. Будь ласка, зробіть резервну копію ваших шаблонів і бази даних перед оновленням."
|
||||
"update_warning": "Всі файли програми та файли шаблонів за замовчуванням будуть перезаписані, коли ви оновите програму за допомогою цієї утиліти. Будь ласка, зробіть резервну копію ваших шаблонів і бази даних перед оновленням.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Резервне копіювання | Резервні копії",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Cập nhật kết thúc",
|
||||
"update_failed": "Cập nhật không thành công",
|
||||
"update_failed_text": "Lấy làm tiếc! Cập nhật của bạn không thành công vào: bước {step}",
|
||||
"update_warning": "Tất cả các tệp ứng dụng và tệp mẫu mặc định sẽ bị ghi đè khi bạn cập nhật ứng dụng bằng công cụ này. Vui lòng sao lưu các mẫu và cơ sở dữ liệu của bạn trước khi thực hiện cập nhật."
|
||||
"update_warning": "Tất cả các tệp ứng dụng và tệp mẫu mặc định sẽ bị ghi đè khi bạn cập nhật ứng dụng bằng công cụ này. Vui lòng sao lưu các mẫu và cơ sở dữ liệu của bạn trước khi thực hiện cập nhật.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Sao lưu | Sao lưu",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "Finishing Update",
|
||||
"update_failed": "Update Failed",
|
||||
"update_failed_text": "Sorry! Your update failed on : {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "Backup | Backups",
|
||||
|
||||
@@ -1326,7 +1326,8 @@
|
||||
"finishing_update": "正完成更新",
|
||||
"update_failed": "更新失敗",
|
||||
"update_failed_text": "抱歉! 你的更新在這步驟中失敗: {step} step",
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating."
|
||||
"update_warning": "All of the application files and default template files will be overwritten when you update the application using this utility. Please take a backup of your templates & database before updating.",
|
||||
"requirements_not_met": "Update cannot continue because some system requirements are not met (including minimum PHP version). Please fix the failed requirements and try again."
|
||||
},
|
||||
"backup": {
|
||||
"title": "備份 | 備份",
|
||||
|
||||
55
package.json
55
package.json
@@ -1,64 +1,61 @@
|
||||
{
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=24"
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"watch": "vite build --watch",
|
||||
"build": "vite build",
|
||||
"serve": "vite preview",
|
||||
"test": "eslint ./resources/scripts --ext .js,.vue"
|
||||
"test": "eslint ./resources/scripts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rvxlab/tailwind-plugin-ios-full-height": "^1.1.0",
|
||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@tailwindcss/vite": "^4.0.0",
|
||||
"@vitejs/plugin-vue": "^6.0.0",
|
||||
"@vue/compiler-sfc": "^3.5.13",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^9.18.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-vue": "^9.32.0",
|
||||
"postcss": "^8.4.49",
|
||||
"eslint": "^10.0.0",
|
||||
"eslint-config-prettier": "^10.0.0",
|
||||
"eslint-plugin-vue": "^10.0.0",
|
||||
"prettier": "^3.4.2",
|
||||
"sass": "^1.83.1",
|
||||
"tailwind-scrollbar": "^3.1.0",
|
||||
"tailwindcss": "^3.4.17"
|
||||
"tailwind-scrollbar": "^4.0.0",
|
||||
"tailwindcss": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/vue": "^1.7.23",
|
||||
"@heroicons/vue": "^2.2.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@stripe/stripe-js": "^2.4.0",
|
||||
"@tiptap/core": "^2.11.2",
|
||||
"@tiptap/extension-link": "^2.11.2",
|
||||
"@tiptap/extension-text-align": "^2.11.2",
|
||||
"@tiptap/pm": "^2.11.2",
|
||||
"@tiptap/starter-kit": "^2.11.2",
|
||||
"@tiptap/vue-3": "^2.11.2",
|
||||
"@types/node": "^20.11.9",
|
||||
"@tiptap/core": "^3.0.0",
|
||||
"@tiptap/extension-text-align": "^3.0.0",
|
||||
"@tiptap/pm": "^3.0.0",
|
||||
"@tiptap/starter-kit": "^3.0.0",
|
||||
"@tiptap/vue-3": "^3.0.0",
|
||||
"@types/node": "^24.0.0",
|
||||
"@vuelidate/components": "^1.2.6",
|
||||
"@vuelidate/core": "^2.0.3",
|
||||
"@vuelidate/validators": "^2.0.4",
|
||||
"@vueuse/core": "^12.4.0",
|
||||
"axios": "0.30.0",
|
||||
"chart.js": "^2.9.4",
|
||||
"@vueuse/core": "^14.0.0",
|
||||
"axios": "1.14.0",
|
||||
"chart.js": "^4.5.1",
|
||||
"guid": "^0.0.12",
|
||||
"laravel-vite-plugin": "^1.1.1",
|
||||
"laravel-vite-plugin": "^3.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"maska": "^3.0.4",
|
||||
"mini-svg-data-uri": "^1.4.4",
|
||||
"moment": "^2.30.1",
|
||||
"path": "^0.12.7",
|
||||
"pinia": "^2.3.0",
|
||||
"pinia": "^3.0.0",
|
||||
"v-money3": "^3.24.1",
|
||||
"v-tooltip": "^4.0.0-beta.17",
|
||||
"vite": "^6.0.7",
|
||||
"vite": "^8.0.0",
|
||||
"vue": "^3.5",
|
||||
"vue-flatpickr-component": "^11.0.5",
|
||||
"vue-flatpickr-component": "^12.0.0",
|
||||
"vue-i18n": "^11.0.1",
|
||||
"vue-router": "^4.5.0",
|
||||
"vue-router": "^5.0.0",
|
||||
"vuedraggable": "^4.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
// postcss.config.js
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
@@ -26,6 +26,12 @@ To get started with InvoiceShelf using Docker Compose, check out the [Installati
|
||||
- [Developer Guide](https://docs.invoiceshelf.com/developer-guide.html)
|
||||
- [API Documentation](https://api-docs.invoiceshelf.com)
|
||||
|
||||
## System Requirements
|
||||
|
||||
- Starting from **v2.2.0** (Laravel 13 upgrade), InvoiceShelf requires **PHP 8.4+**.
|
||||
- Before updating from the app settings, verify your server PHP version and required extensions.
|
||||
- The in-app updater checks requirements and blocks the update if they are not met.
|
||||
|
||||
## Download
|
||||
|
||||
- [Download Link](https://invoiceshelf.com)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user