Compare commits
22
Commits
c3d96f24ff
..
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1981673a2 | ||
|
|
84f5f0c788 | ||
|
|
d2bd589c96 | ||
|
|
97e2c9e192 | ||
|
|
23f9154eb6 | ||
|
|
9ddcc0adb5 | ||
|
|
a2ed9a9838 | ||
|
|
937004a48c | ||
|
|
bd6e311a73 | ||
|
|
a628dc1424 | ||
|
|
7fa56f7584 | ||
|
|
0ebd39f4fc | ||
|
|
1bd4ffa0f7 | ||
|
|
a6ec45f685 | ||
|
|
474e44ca0c | ||
|
|
75f0a8843d | ||
|
|
7963ddc982 | ||
|
|
71cc2d2676 | ||
|
|
fb5a90f470 | ||
|
|
5d472dc33b | ||
|
|
bf0c97db25 | ||
|
|
bb93f0be00 |
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!Dockerfile
|
||||
@@ -0,0 +1,39 @@
|
||||
APP_NAME=Pollux
|
||||
APP_ENV=local
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost:8000
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=db
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=pollux
|
||||
DB_USERNAME=pollux
|
||||
DB_PASSWORD=secret
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
QUEUE_DRIVER=sync
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
FROM composer:2.8 AS composer
|
||||
|
||||
FROM php:7.4-cli
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends libonig-dev libzip-dev \
|
||||
&& docker-php-ext-install -j"$(nproc)" mbstring pdo_mysql zip \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY --from=composer /usr/bin/composer /usr/bin/composer
|
||||
|
||||
WORKDIR /var/www
|
||||
@@ -0,0 +1,96 @@
|
||||
# Pollux
|
||||
|
||||
Pollux is a small Laravel 5.6 bookkeeping application for managing bookings,
|
||||
projects, people, targets, and reports.
|
||||
|
||||
## Local development
|
||||
|
||||
The application targets PHP 7.4 and MySQL 5.7. Those old runtimes are run in
|
||||
Docker so they do not have to be installed on the host. [mise](https://mise.jdx.dev/)
|
||||
manages the host-side tools: Just and Node 10 (required by the old Laravel Mix 2
|
||||
asset pipeline).
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Docker with Compose v2 (`docker compose`)
|
||||
- [mise](https://mise.jdx.dev/)
|
||||
|
||||
### First run
|
||||
|
||||
```sh
|
||||
mise install
|
||||
just setup
|
||||
just up
|
||||
```
|
||||
|
||||
Then open <http://localhost:8000>. A development login is created automatically:
|
||||
|
||||
- **Email:** `dev@pollux.local`
|
||||
- **Password:** `password`
|
||||
|
||||
`just setup` builds the PHP image, installs Composer dependencies, creates `.env`
|
||||
from `.env.docker.example`, generates `APP_KEY`, starts MySQL, runs migrations,
|
||||
and loads the constant and demo data.
|
||||
|
||||
### Everyday commands
|
||||
|
||||
| Command | Description |
|
||||
| --- | --- |
|
||||
| `just up` | Start the app and database in the foreground |
|
||||
| `just up -d` | Start the app and database in the background |
|
||||
| `just down` | Stop the app and database |
|
||||
| `just logs` | Follow container logs |
|
||||
| `just artisan <command>` | Run an Artisan command |
|
||||
| `just composer <command>` | Run a Composer command |
|
||||
| `just shell` | Open a shell in the app container |
|
||||
| `just db` | Open a MySQL shell |
|
||||
| `just migrate` | Run migrations |
|
||||
| `just seed` | Add the demo/test dataset to an existing database |
|
||||
| `just seed-real` | Recreate the database and load the full dataset from `database/seeds/data/real` |
|
||||
| `just fresh` | Drop and recreate the database, then load demo data |
|
||||
| `just test` | Run PHPUnit |
|
||||
| `just assets` | Install npm packages and build frontend assets |
|
||||
| `just watch` | Rebuild frontend assets on change |
|
||||
|
||||
Run `just --list` to see the full list.
|
||||
|
||||
### Database
|
||||
|
||||
MySQL is exposed on host port **3307** so it does not clash with a local MySQL
|
||||
on 3306. The database is `pollux` with username `pollux` and password `secret`.
|
||||
The app container connects to the `db` service on port 3306.
|
||||
|
||||
Data lives in the Docker volume `pollux_mysql-data`. `just down` keeps the data;
|
||||
use `docker compose down -v` if you want to remove it as well.
|
||||
|
||||
### Frontend assets
|
||||
|
||||
Node 10 is pinned in `mise.toml` because Laravel Mix 2 and `node-sass` do not run
|
||||
on current Node versions. Prebuilt assets are committed, so `just assets` is not
|
||||
needed just to run the application.
|
||||
|
||||
### Tests
|
||||
|
||||
```sh
|
||||
just test
|
||||
```
|
||||
|
||||
## Legacy compatibility notes
|
||||
|
||||
This project uses several old dependencies, so a few small compatibility fixes
|
||||
are included:
|
||||
|
||||
- `phpdocumentor/phpdocumentor` 2.* was removed from `require-dev`. It requires
|
||||
Symfony 2.x, conflicts with Laravel 5.6, and was never present in
|
||||
`composer.lock`.
|
||||
- `scripts/patch-package-manifest.php` runs after Composer's autoload dump. It
|
||||
adds Composer 2 support to Laravel 5.6's package discovery, which otherwise
|
||||
fails with `Undefined index: name`.
|
||||
- `fzaninotto/faker` was updated to 1.9.2 for PHP 7.4 compatibility.
|
||||
- `bookings.note` is created as `TEXT` because the full dataset in
|
||||
`database/seeds/data/real` contains notes longer than the default
|
||||
191-character string length.
|
||||
|
||||
## License
|
||||
|
||||
Pollux is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
||||
@@ -24,48 +24,15 @@ class BookingsController extends Controller
|
||||
*/
|
||||
public function index($year)
|
||||
{
|
||||
$bookings = Booking::with('subBookings.accountType.accountClass.ioType',
|
||||
'subBookings.project')
|
||||
->whereYear('date', '=', $year)
|
||||
->orderBy('date')
|
||||
->get()
|
||||
->groupBy( function ($item) {
|
||||
return Carbon::parse($item->date)->format('n');
|
||||
});
|
||||
$cashbook = $this->getCashbook($year);
|
||||
|
||||
$sums = array();
|
||||
|
||||
$startBalance = SubBooking::balanceAt($year - 1 . '-12-31');
|
||||
$sums[0]['balance'] = $startBalance;
|
||||
return view('bookings.index', $cashbook);
|
||||
}
|
||||
|
||||
$expeditures = SubBooking::expedituresInInterval($year . '-01-01', $year . '-12-31', true);
|
||||
|
||||
$incomes = SubBooking::incomesInInterval($year . '-01-01', $year . '-12-31', true);
|
||||
public function report($year) {
|
||||
$cashbook = $this->getCashbook($year);
|
||||
|
||||
// Create an array with the following properties:
|
||||
// 'balance' - The account balance at the last day of a month
|
||||
// 'expeditures' - the sum of all expeditures in this month
|
||||
// 'incomes' - the sum of all incomes in this month plus the account
|
||||
// balance of the previous month
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
$currExpeditures = $expeditures->where('month', '=', $month)->first()->expeditures;
|
||||
|
||||
$currIncomes = $expeditures->where('month', '<', $month)->sum('expeditures')
|
||||
+ $incomes->where('month', '<=', $month)->sum('incomes')
|
||||
+ $startBalance;
|
||||
|
||||
$currBalance = $currExpeditures + $currIncomes;
|
||||
|
||||
$sums[$month]['expeditures'] = $currExpeditures;
|
||||
$sums[$month]['incomes'] = $currIncomes;
|
||||
$sums[$month]['balance'] = $currBalance;
|
||||
}
|
||||
|
||||
$firstDateString = Carbon::parse(Booking::firstDate());
|
||||
$firstDate['Y'] = $firstDateString->format('Y');
|
||||
$firstDate['m'] = $firstDateString->format('m');
|
||||
|
||||
return view('bookings.index', compact('bookings', 'year', 'sums', 'firstDate'));
|
||||
return view('bookings.print', $cashbook);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,7 +252,7 @@ class BookingsController extends Controller
|
||||
// ... and create a list of the open targets to show it in the form as
|
||||
// dropdown menu.
|
||||
$openTargetsArray = [];
|
||||
|
||||
|
||||
foreach ($openTargets as $personTargets) {
|
||||
foreach ($personTargets as $personTarget) {
|
||||
$person = $personTarget->person;
|
||||
@@ -306,7 +273,7 @@ class BookingsController extends Controller
|
||||
|
||||
foreach ($projects as $project) {
|
||||
$timeOfProject = '';
|
||||
|
||||
|
||||
if ($project->start_date <= today() and $project->end_date >= today()) {
|
||||
$timeOfProject = 'Laufende Projekte';
|
||||
} elseif ($project->start_date > today()) {
|
||||
@@ -314,7 +281,7 @@ class BookingsController extends Controller
|
||||
} else {
|
||||
$timeOfProject = 'Vergangene Projekte';
|
||||
}
|
||||
|
||||
|
||||
$projectsArray['Vergangene Projekte'][$project->id] = $project->name;
|
||||
}
|
||||
|
||||
@@ -346,4 +313,49 @@ class BookingsController extends Controller
|
||||
|
||||
return compact('openTargetsArray', 'projectsArray', 'accountTypeArray');
|
||||
}
|
||||
|
||||
private function getCashbook($year) {
|
||||
$bookings = Booking::with('subBookings.accountType.accountClass.ioType',
|
||||
'subBookings.project')
|
||||
->whereYear('date', '=', $year)
|
||||
->orderBy('date')
|
||||
->get()
|
||||
->groupBy( function ($item) {
|
||||
return Carbon::parse($item->date)->format('n');
|
||||
});
|
||||
|
||||
$sums = array();
|
||||
|
||||
$startBalance = SubBooking::balanceAt($year - 1 . '-12-31');
|
||||
$sums[0]['balance'] = $startBalance;
|
||||
|
||||
$expeditures = SubBooking::expedituresInInterval($year . '-01-01', $year . '-12-31', true);
|
||||
|
||||
$incomes = SubBooking::incomesInInterval($year . '-01-01', $year . '-12-31', true);
|
||||
|
||||
// Create an array with the following properties:
|
||||
// 'balance' - The account balance at the last day of a month
|
||||
// 'expeditures' - the sum of all expeditures in this month
|
||||
// 'incomes' - the sum of all incomes in this month plus the account
|
||||
// balance of the previous month
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
$currExpeditures = $expeditures->where('month', '=', $month)->first()->expeditures;
|
||||
|
||||
$currIncomes = $expeditures->where('month', '<', $month)->sum('expeditures')
|
||||
+ $incomes->where('month', '<=', $month)->sum('incomes')
|
||||
+ $startBalance;
|
||||
|
||||
$currBalance = $currExpeditures + $currIncomes;
|
||||
|
||||
$sums[$month]['expeditures'] = $currExpeditures;
|
||||
$sums[$month]['incomes'] = $currIncomes;
|
||||
$sums[$month]['balance'] = $currBalance;
|
||||
}
|
||||
|
||||
$firstDateString = Carbon::parse(Booking::firstDate());
|
||||
$firstDate['Y'] = $firstDateString->format('Y');
|
||||
$firstDate['m'] = $firstDateString->format('m');
|
||||
|
||||
return compact('bookings', 'year', 'sums', 'firstDate');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +118,13 @@ class PeopleController extends Controller
|
||||
// Show the delete dialog for a given person
|
||||
public function delete(Person $person)
|
||||
{
|
||||
$person->load('targets:id,person_id,io_type_id,amount',
|
||||
'targets.ioType:id,factor',
|
||||
'targets.actuals:id,person_target_id,account_type_id,amount',
|
||||
'targets.actuals.accountType:id,account_class_id',
|
||||
'targets.actuals.accountType.accountClass:id,io_type_id',
|
||||
'targets.actuals.accountType.accountClass.ioType:id,factor');
|
||||
|
||||
return view('people.delete', compact('person'));
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,106 @@ class ReportsController extends Controller
|
||||
return view('reports.scopes.compact', compact('scopes', 'year',
|
||||
'startBalance', 'endBalance'));
|
||||
} elseif ($type == 'detailed') {
|
||||
return view('reports.scopes.detailed');
|
||||
$yearFilter = function($query) use ($year) {
|
||||
$query->whereHas('booking', function($query) use ($year) {
|
||||
$query->whereYear('date', $year);
|
||||
});
|
||||
};
|
||||
|
||||
$scopes = Scope::select('id', 'name')
|
||||
->with([
|
||||
'accountClasses:id,io_type_id,scope_id,name',
|
||||
'accountClasses.ioType:id,factor',
|
||||
'accountClasses.accountTypes' => function($query) use ($year, $yearFilter) {
|
||||
return $query->select('id', 'account_class_id', 'name', 'number')
|
||||
->whereHas('subBookings', $yearFilter)
|
||||
->with(['subBookings' => $yearFilter,
|
||||
'subBookings.booking:id,person_or_company,date']);
|
||||
}
|
||||
])->get();
|
||||
|
||||
foreach ($scopes as $scope) {
|
||||
foreach ($scope->accountClasses as $accountClass) {
|
||||
$accountClass->amount =
|
||||
$accountClass->accountTypes->sum(function ($accountType) {
|
||||
return $accountType->subBookings->sum('amount');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return view('reports.scopes.detailed', compact('scopes', 'year'));
|
||||
} else {
|
||||
abort(404);
|
||||
}
|
||||
}
|
||||
|
||||
public function printScopes($type, $year)
|
||||
{
|
||||
if ($type == 'compact') {
|
||||
$yearFilter = function($query) use ($year) {
|
||||
$query->whereHas('booking', function($query) use ($year) {
|
||||
$query->whereYear('date', $year);
|
||||
});
|
||||
};
|
||||
|
||||
$scopes = Scope::select('id', 'name')
|
||||
->with([
|
||||
'accountClasses:id,io_type_id,scope_id,name',
|
||||
'accountClasses.ioType:id,factor',
|
||||
'accountClasses.accountTypes' => function($query) use ($year, $yearFilter) {
|
||||
return $query->select('id', 'account_class_id', 'name', 'number')
|
||||
->whereHas('subBookings', $yearFilter)
|
||||
->with(['subBookings' => $yearFilter]);
|
||||
}
|
||||
])->get();
|
||||
|
||||
foreach ($scopes as $scope) {
|
||||
foreach ($scope->accountClasses as $accountClass) {
|
||||
$accountClass->amount =
|
||||
$accountClass->accountTypes->sum(function ($accountType) {
|
||||
return $accountType->subBookings->sum('amount');
|
||||
});
|
||||
}
|
||||
|
||||
$scope->balance = $scope->accountClasses->sum(function ($accountClass) {
|
||||
return $accountClass->amount * $accountClass->ioType->factor;
|
||||
});
|
||||
}
|
||||
|
||||
$startBalance = SubBooking::balanceAt(lastDayOfYear($year - 1));
|
||||
$endBalance = $startBalance + $scopes->sum('balance');
|
||||
|
||||
return view('reports.scopes.compact_print', compact('scopes', 'year',
|
||||
'startBalance', 'endBalance'));
|
||||
} elseif ($type == 'detailed') {
|
||||
$yearFilter = function($query) use ($year) {
|
||||
$query->whereHas('booking', function($query) use ($year) {
|
||||
$query->whereYear('date', $year);
|
||||
});
|
||||
};
|
||||
|
||||
$scopes = Scope::select('id', 'name')
|
||||
->with([
|
||||
'accountClasses:id,io_type_id,scope_id,name',
|
||||
'accountClasses.ioType:id,factor',
|
||||
'accountClasses.accountTypes' => function($query) use ($year, $yearFilter) {
|
||||
return $query->select('id', 'account_class_id', 'name', 'number')
|
||||
->whereHas('subBookings', $yearFilter)
|
||||
->with(['subBookings' => $yearFilter,
|
||||
'subBookings.booking:id,person_or_company,date']);
|
||||
}
|
||||
])->get();
|
||||
|
||||
foreach ($scopes as $scope) {
|
||||
foreach ($scope->accountClasses as $accountClass) {
|
||||
$accountClass->amount =
|
||||
$accountClass->accountTypes->sum(function ($accountType) {
|
||||
return $accountType->subBookings->sum('amount');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return view('reports.scopes.detailed_print', compact('scopes', 'year'));
|
||||
} else {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use App\CustomValidator;
|
||||
use Validator;
|
||||
@@ -18,6 +19,9 @@ class AppServiceProvider extends ServiceProvider
|
||||
Validator::resolver(function ($translator, $data, $rules, $messages) {
|
||||
return new CustomValidator($translator, $data, $rules, $messages);
|
||||
});
|
||||
|
||||
// Set default string length in order to run on older versions of MySQL
|
||||
Schema::defaultStringLength(191);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
name: pollux
|
||||
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
working_dir: /var/www
|
||||
user: "${UID:-1000}:${GID:-1000}"
|
||||
environment:
|
||||
HOME: /tmp
|
||||
COMPOSER_HOME: /tmp/composer
|
||||
APP_URL: http://localhost:8000
|
||||
DB_CONNECTION: mysql
|
||||
DB_HOST: db
|
||||
DB_PORT: "3306"
|
||||
DB_DATABASE: pollux
|
||||
DB_USERNAME: pollux
|
||||
DB_PASSWORD: secret
|
||||
volumes:
|
||||
- .:/var/www
|
||||
ports:
|
||||
- "8000:8000"
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
command: php artisan serve --host=0.0.0.0 --port=8000
|
||||
|
||||
db:
|
||||
image: mysql:5.7
|
||||
environment:
|
||||
MYSQL_DATABASE: pollux
|
||||
MYSQL_USER: pollux
|
||||
MYSQL_PASSWORD: secret
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
volumes:
|
||||
- mysql-data:/var/lib/mysql
|
||||
ports:
|
||||
- "3307:3306"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uroot -proot --silent"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 20
|
||||
|
||||
volumes:
|
||||
mysql-data:
|
||||
+2
-2
@@ -22,8 +22,7 @@
|
||||
"fzaninotto/faker": "^1.4",
|
||||
"mockery/mockery": "^1.0",
|
||||
"nunomaduro/collision": "^2.0",
|
||||
"phpunit/phpunit": "^7.0",
|
||||
"phpdocumentor/phpdocumentor": "2.*"
|
||||
"phpunit/phpunit": "^7.0"
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
@@ -57,6 +56,7 @@
|
||||
],
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php scripts/patch-package-manifest.php",
|
||||
"@php artisan package:discover"
|
||||
]
|
||||
},
|
||||
|
||||
Generated
+24
-18
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "68e5550c8775420cfdaef12858446b78",
|
||||
@@ -1118,12 +1118,12 @@
|
||||
"version": "1.25.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"url": "https://github.com/CarbonPHP/carbon.git",
|
||||
"reference": "cbcf13da0b531767e39eb86e9687f5deba9857b4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cbcf13da0b531767e39eb86e9687f5deba9857b4",
|
||||
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/cbcf13da0b531767e39eb86e9687f5deba9857b4",
|
||||
"reference": "cbcf13da0b531767e39eb86e9687f5deba9857b4",
|
||||
"shasum": ""
|
||||
},
|
||||
@@ -2604,12 +2604,12 @@
|
||||
"version": "v2.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vlucas/phpdotenv.git",
|
||||
"url": "https://github.com/phpdotenv/phpdotenv.git",
|
||||
"reference": "8abb4f9aa89ddea9d52112c65bbe8d0125e2fa8e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/8abb4f9aa89ddea9d52112c65bbe8d0125e2fa8e",
|
||||
"url": "https://api.github.com/repos/phpdotenv/phpdotenv/zipball/8abb4f9aa89ddea9d52112c65bbe8d0125e2fa8e",
|
||||
"reference": "8abb4f9aa89ddea9d52112c65bbe8d0125e2fa8e",
|
||||
"shasum": ""
|
||||
},
|
||||
@@ -2656,12 +2656,12 @@
|
||||
"version": "v3.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/barryvdh/laravel-debugbar.git",
|
||||
"url": "https://github.com/fruitcake/laravel-debugbar.git",
|
||||
"reference": "5b68f3972083a7eeec0d6f161962fcda71a127c0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/5b68f3972083a7eeec0d6f161962fcda71a127c0",
|
||||
"url": "https://api.github.com/repos/fruitcake/laravel-debugbar/zipball/5b68f3972083a7eeec0d6f161962fcda71a127c0",
|
||||
"reference": "5b68f3972083a7eeec0d6f161962fcda71a127c0",
|
||||
"shasum": ""
|
||||
},
|
||||
@@ -2836,16 +2836,16 @@
|
||||
},
|
||||
{
|
||||
"name": "fzaninotto/faker",
|
||||
"version": "v1.8.0",
|
||||
"version": "v1.9.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fzaninotto/Faker.git",
|
||||
"reference": "f72816b43e74063c8b10357394b6bba8cb1c10de"
|
||||
"reference": "848d8125239d7dbf8ab25cb7f054f1a630e68c2e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fzaninotto/Faker/zipball/f72816b43e74063c8b10357394b6bba8cb1c10de",
|
||||
"reference": "f72816b43e74063c8b10357394b6bba8cb1c10de",
|
||||
"url": "https://api.github.com/repos/fzaninotto/Faker/zipball/848d8125239d7dbf8ab25cb7f054f1a630e68c2e",
|
||||
"reference": "848d8125239d7dbf8ab25cb7f054f1a630e68c2e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2854,12 +2854,12 @@
|
||||
"require-dev": {
|
||||
"ext-intl": "*",
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7",
|
||||
"squizlabs/php_codesniffer": "^1.5"
|
||||
"squizlabs/php_codesniffer": "^2.9.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.8-dev"
|
||||
"dev-master": "1.9-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2882,7 +2882,12 @@
|
||||
"faker",
|
||||
"fixtures"
|
||||
],
|
||||
"time": "2018-07-12T10:23:15+00:00"
|
||||
"support": {
|
||||
"issues": "https://github.com/fzaninotto/Faker/issues",
|
||||
"source": "https://github.com/fzaninotto/Faker/tree/v1.9.2"
|
||||
},
|
||||
"abandoned": true,
|
||||
"time": "2020-12-11T09:56:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "hamcrest/hamcrest-php",
|
||||
@@ -4431,12 +4436,12 @@
|
||||
"version": "1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozart/assert.git",
|
||||
"url": "https://github.com/webmozarts/assert.git",
|
||||
"reference": "0df1908962e7a3071564e857d86874dad1ef204a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
|
||||
"url": "https://api.github.com/repos/webmozarts/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
|
||||
"reference": "0df1908962e7a3071564e857d86874dad1ef204a",
|
||||
"shasum": ""
|
||||
},
|
||||
@@ -4479,11 +4484,12 @@
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "dev",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {},
|
||||
"prefer-stable": true,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": "^7.1.3"
|
||||
},
|
||||
"platform-dev": []
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
|
||||
@@ -25,8 +25,9 @@ class CreateBookingsTable extends Migration
|
||||
// The name of the person or company which the booking belongs to
|
||||
$table->string('person_or_company');
|
||||
|
||||
// An additional note to the booking
|
||||
$table->string('note')->nullable();
|
||||
// An additional note to the booking. The real dataset contains
|
||||
// notes longer than the 191-character default string length.
|
||||
$table->text('note')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DevUserSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Create a local development login.
|
||||
*
|
||||
* Email: dev@pollux.local
|
||||
* Password: password
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
App\User::updateOrCreate(
|
||||
['email' => 'dev@pollux.local'],
|
||||
[
|
||||
'name' => 'Dev User',
|
||||
'password' => bcrypt('password'),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
set shell := ["bash", "-uc"]
|
||||
|
||||
# Keep files created by containers owned by the host user.
|
||||
export UID := `id -u`
|
||||
export GID := `id -g`
|
||||
|
||||
default:
|
||||
@just --list
|
||||
|
||||
# First-time setup: build, install PHP deps, create .env, migrate and seed.
|
||||
setup:
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [ ! -f .env ]; then
|
||||
cp .env.docker.example .env
|
||||
fi
|
||||
|
||||
docker compose build
|
||||
docker compose run --rm --no-deps app composer install
|
||||
|
||||
if ! grep -q '^APP_KEY=base64:' .env; then
|
||||
docker compose run --rm --no-deps app php artisan key:generate --force
|
||||
fi
|
||||
|
||||
docker compose up -d --wait db
|
||||
docker compose run --rm app php artisan migrate --force
|
||||
|
||||
# Only seed the demo data on a fresh database.
|
||||
if [ "$(docker compose exec -T db mysql -N -B -upollux -psecret pollux -e 'SELECT COUNT(*) FROM scopes' 2>/dev/null || echo 0)" = "0" ]; then
|
||||
docker compose run --rm app php artisan db:seed --class=ConstantsSeeder --force
|
||||
docker compose run --rm app php artisan db:seed --class=TestDataSeeder --force
|
||||
else
|
||||
echo "Database already seeded; skipping demo data."
|
||||
fi
|
||||
|
||||
docker compose run --rm app php artisan db:seed --class=DevUserSeeder --force
|
||||
|
||||
echo "Setup complete. Run 'just up', then open http://localhost:8000"
|
||||
echo "Login: dev@pollux.local / password"
|
||||
|
||||
# Start the app and database in the foreground. Use `just up -d` for background.
|
||||
up *args:
|
||||
docker compose up --build {{args}}
|
||||
|
||||
# Stop the app and database.
|
||||
down:
|
||||
docker compose down
|
||||
|
||||
# Tail logs. Optionally pass a service name: just logs app
|
||||
logs *args:
|
||||
docker compose logs -f {{args}}
|
||||
|
||||
# Run an artisan command: just artisan route:list
|
||||
artisan *args:
|
||||
docker compose run --rm app php artisan {{args}}
|
||||
|
||||
# Run a composer command: just composer require foo/bar
|
||||
composer *args:
|
||||
docker compose run --rm app composer {{args}}
|
||||
|
||||
# Open a shell in the app container.
|
||||
shell:
|
||||
docker compose run --rm app bash
|
||||
|
||||
# Open a MySQL shell.
|
||||
db:
|
||||
docker compose up -d --wait db
|
||||
docker compose exec db mysql -upollux -psecret pollux
|
||||
|
||||
# Run migrations.
|
||||
migrate:
|
||||
docker compose run --rm app php artisan migrate
|
||||
|
||||
# Add the demo/test dataset to an existing database.
|
||||
seed:
|
||||
docker compose run --rm app php artisan db:seed --class=TestDataSeeder
|
||||
|
||||
# Recreate the database and load the full dataset from database/seeds/data/real.
|
||||
seed-real:
|
||||
docker compose run --rm app php artisan migrate:fresh
|
||||
docker compose run --rm app php artisan db:seed --force
|
||||
docker compose run --rm app php artisan db:seed --class=DevUserSeeder --force
|
||||
|
||||
# Recreate the database and load test data.
|
||||
fresh:
|
||||
docker compose run --rm app php artisan migrate:fresh
|
||||
docker compose run --rm app php artisan db:seed --class=ConstantsSeeder
|
||||
docker compose run --rm app php artisan db:seed --class=TestDataSeeder
|
||||
docker compose run --rm app php artisan db:seed --class=DevUserSeeder
|
||||
|
||||
# Run the test suite.
|
||||
test *args:
|
||||
docker compose run --rm --no-deps app vendor/bin/phpunit {{args}}
|
||||
|
||||
# Build frontend assets (uses the mise-pinned Node 10).
|
||||
assets:
|
||||
mise exec -- npm install
|
||||
mise exec -- npm run dev
|
||||
|
||||
# Watch frontend assets.
|
||||
watch:
|
||||
mise exec -- npm run watch
|
||||
@@ -0,0 +1,7 @@
|
||||
[tools]
|
||||
# Old Laravel Mix 2 / node-sass toolchain; use Node 10 for asset builds.
|
||||
node = "10.24.1"
|
||||
just = "1.59.0"
|
||||
|
||||
[env]
|
||||
COMPOSE_PROJECT_NAME = "pollux"
|
||||
@@ -1,65 +0,0 @@
|
||||
<p align="center"><img src="https://laravel.com/assets/img/components/logo-laravel.svg"></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/d/total.svg" alt="Total Downloads"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/v/stable.svg" alt="Latest Stable Version"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/license.svg" alt="License"></a>
|
||||
</p>
|
||||
|
||||
## About Laravel
|
||||
|
||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as:
|
||||
|
||||
- [Simple, fast routing engine](https://laravel.com/docs/routing).
|
||||
- [Powerful dependency injection container](https://laravel.com/docs/container).
|
||||
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
|
||||
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
|
||||
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
|
||||
- [Robust background job processing](https://laravel.com/docs/queues).
|
||||
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
|
||||
|
||||
Laravel is accessible, yet powerful, providing tools needed for large, robust applications.
|
||||
|
||||
## Learning Laravel
|
||||
|
||||
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of any modern web application framework, making it a breeze to get started learning the framework.
|
||||
|
||||
If you're not in the mood to read, [Laracasts](https://laracasts.com) contains over 1100 video tutorials on a range of topics including Laravel, modern PHP, unit testing, JavaScript, and more. Boost the skill level of yourself and your entire team by digging into our comprehensive video library.
|
||||
|
||||
## Laravel Sponsors
|
||||
|
||||
We would like to extend our thanks to the following sponsors for helping fund on-going Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell):
|
||||
|
||||
- **[Vehikl](https://vehikl.com/)**
|
||||
- **[Tighten Co.](https://tighten.co)**
|
||||
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
|
||||
- **[Cubet Techno Labs](https://cubettech.com)**
|
||||
- **[British Software Development](https://www.britishsoftware.co)**
|
||||
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
|
||||
- [UserInsights](https://userinsights.com)
|
||||
- [Fragrantica](https://www.fragrantica.com)
|
||||
- [SOFTonSOFA](https://softonsofa.com/)
|
||||
- [User10](https://user10.com)
|
||||
- [Soumettre.fr](https://soumettre.fr/)
|
||||
- [CodeBrisk](https://codebrisk.com)
|
||||
- [1Forge](https://1forge.com)
|
||||
- [TECPRESSO](https://tecpresso.co.jp/)
|
||||
- [Runtime Converter](http://runtimeconverter.com/)
|
||||
- [WebL'Agence](https://weblagence.com/)
|
||||
- [Invoice Ninja](https://www.invoiceninja.com)
|
||||
- [iMi digital](https://www.imi-digital.de/)
|
||||
- [Earthlink](https://www.earthlink.ro/)
|
||||
- [Steadfast Collective](https://steadfastcollective.com/)
|
||||
|
||||
## Contributing
|
||||
|
||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
|
||||
|
||||
## Security Vulnerabilities
|
||||
|
||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
|
||||
|
||||
## License
|
||||
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
||||
@@ -3,41 +3,53 @@
|
||||
@section('title', 'Buchung löschen')
|
||||
|
||||
@section('subnav')
|
||||
<a href='{{ url()->previous() }}'>Zurück</a>
|
||||
<a href='{{ url()->previous() }}' class='btn btn-outline-secondary'>Zurück</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<h2>@yield('title')</h2>
|
||||
<form action='/bookings/{{ $booking->id }}' method='post'>
|
||||
<form action='/bookings/{{ $booking->id }}' method='post' class='mt-4 text-center'>
|
||||
{{ method_field('delete') }}
|
||||
{{ csrf_field() }}
|
||||
<p>Soll folgende Buchung und alle ihre Teilbuchungen wirklich gelöscht
|
||||
werden?</p>
|
||||
<div class='alert alert-danger'>
|
||||
<p>
|
||||
Soll folgende Buchung und alle ihre Teilbuchungen wirklich
|
||||
gelöscht werden?
|
||||
</p>
|
||||
|
||||
<table border='1'>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Positionen</th>
|
||||
<th>Person / Firma</th>
|
||||
<th>Betrag</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ $booking->date }}</td>
|
||||
<td>{{ $booking->reference }}</td>
|
||||
<td>{{ $booking->person_or_company }}</td>
|
||||
<td align='right'>{{ formatAmount($booking->signedAmount(), true, true) }}</td>
|
||||
</tr>
|
||||
@foreach($booking->subBookings as $subBooking)
|
||||
<table class='table'>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{{ $subBooking->reference }}</td>
|
||||
<td></td>
|
||||
<td align='right'>{{ formatAmount($subBooking->signedAmount(), true, true) }}</td>
|
||||
<th>Datum</th>
|
||||
<th>Positionen</th>
|
||||
<th>Person / Firma</th>
|
||||
<th>Betrag</th>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
<tr>
|
||||
<td>{{ formatDate($booking->date) }}</td>
|
||||
<td>{{ $booking->reference }}</td>
|
||||
<td>{{ $booking->person_or_company }}</td>
|
||||
<td align='right'>
|
||||
{{
|
||||
formatAmount($booking->signedAmount(), true, true)
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
@foreach($booking->subBookings as $subBooking)
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{{ $subBooking->reference }}</td>
|
||||
<td></td>
|
||||
<td align='right'>
|
||||
{{
|
||||
formatAmount($subBooking->signedAmount(), true, true)
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
|
||||
<button type="submit" id="submit">Ja</button>
|
||||
<button class='btn btn-primary' type="submit" id="submit">Ja</button>
|
||||
<a href="{{ url()->previous() }}" class="btn btn-outline-secondary">Nein</a>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
<a href='/reports/balances/{{ $year }}' class="btn btn-outline-warning">HS-Rechnung</a>
|
||||
<a href='/reports/scopes/compact/{{ $year }}' class="btn
|
||||
btn-outline-warning">Abrechnung</a>
|
||||
<a href='/reports/scopes/detailed/{{ $year }}' class="btn
|
||||
btn-outline-warning">Konten</a>
|
||||
</li>
|
||||
@endsection
|
||||
|
||||
@@ -21,8 +23,8 @@
|
||||
{{ $year + 1 }} <i class="fas fa-chevron-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
<table class='table table-striped table-bordered'>
|
||||
<tr>
|
||||
<table class='table table-bordered table-hover'>
|
||||
<tr class='table-secondary'>
|
||||
<th>Datum</th>
|
||||
<th>Positionen</th>
|
||||
<th>Person / Firma</th>
|
||||
@@ -30,7 +32,7 @@
|
||||
<th>Eingang (H)</th>
|
||||
<th>Konto</th>
|
||||
<th>Projekt</th>
|
||||
<th></th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
@for ($month = 1; $month <= 12; $month++)
|
||||
@if ((
|
||||
@@ -42,15 +44,15 @@
|
||||
or $firstDate['Y'] == $year
|
||||
and $firstDate['m'] <= $month
|
||||
))
|
||||
<tr style='color: red; font-weight: bold'>
|
||||
<td>{{ startOfMonth($year, $month) }}</td>
|
||||
<td>Saldo</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>{!! formatAmount($sums[$month - 1]['balance']) !!}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<tr style='color:#ff0000'>
|
||||
<th>{{ startOfMonth($year, $month) }}</th>
|
||||
<th>Saldo</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th>{!! formatAmount($sums[$month - 1]['balance']) !!}</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@endif
|
||||
@if (isset($bookings[$month]))
|
||||
@@ -81,10 +83,18 @@
|
||||
</td>
|
||||
<td>
|
||||
<div class='btn-group' role='group' aria-label='Basic example'>
|
||||
<a href='/bookings/{{ $booking->id }}/edit' class='btn btn-success'>
|
||||
<a href='/bookings/{{ $booking->id }}/edit'
|
||||
class='btn btn-success'
|
||||
data-toggle='tooltip'
|
||||
data-placement='bottom'
|
||||
title='Bearbeiten'>
|
||||
<i class='fas fa-edit'></i>
|
||||
</a>
|
||||
<a href='/bookings/{{ $booking->id }}/delete' class='btn btn-danger'>
|
||||
<a href='/bookings/{{ $booking->id }}/delete'
|
||||
class='btn btn-danger'
|
||||
data-toggle='tooltip'
|
||||
data-placement='bottom'
|
||||
title='Löschen'>
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
</div>
|
||||
@@ -92,7 +102,7 @@
|
||||
</tr>
|
||||
@if (!$booking->isSimple())
|
||||
@foreach ($booking->subBookings as $subBooking)
|
||||
<tr>
|
||||
<tr style='font-style:italic'>
|
||||
<td></td>
|
||||
<td>{{ $subBooking->reference }}</td>
|
||||
<td></td>
|
||||
@@ -129,29 +139,29 @@
|
||||
or $firstDate['Y'] == $year
|
||||
and $firstDate['m'] <= $month
|
||||
))
|
||||
<tr style='color: #000080; font-weight: bold'>
|
||||
<td>
|
||||
<tr style='color:#000080'>
|
||||
<th>
|
||||
{{ endOfMonth($year, $month) }}
|
||||
</td>
|
||||
<td>Monatsabschluss</td>
|
||||
<td></td>
|
||||
<td>{!! formatAmount($sums[$month]['expeditures']) !!}</td>
|
||||
<td>{!! formatAmount($sums[$month]['incomes']) !!}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</th>
|
||||
<th>Monatsabschluss</th>
|
||||
<th></th>
|
||||
<th>{!! formatAmount($sums[$month]['expeditures']) !!}</th>
|
||||
<th>{!! formatAmount($sums[$month]['incomes']) !!}</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr style='color: red; font-weight: bold'>
|
||||
<td>
|
||||
<tr style='color:#ff0000'>
|
||||
<th>
|
||||
{{ endOfMonth($year, $month) }}
|
||||
</td>
|
||||
<td>Saldo</td>
|
||||
<td></td>
|
||||
<td>{!! formatAmount($sums[$month]['balance']) !!}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</th>
|
||||
<th>Saldo</th>
|
||||
<th></th>
|
||||
<th>{!! formatAmount($sums[$month]['balance']) !!}</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
@for ($i = 0; $i < 8; $i++)
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
@extends('layout.print')
|
||||
|
||||
@section('title', 'Kassenbuch ' . $year)
|
||||
|
||||
@section('content')
|
||||
@for ($month = 1; $month <= 12; $month++)
|
||||
<table class='table table-sm table-bordered' style='page-break-after: always'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Positionen</th>
|
||||
<th>Person / Firma</th>
|
||||
<th style='width:2.6cm'>Ausgang</th>
|
||||
<th style='width:2.6cm'>Eingang</th>
|
||||
<th>Konto</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@if ((
|
||||
date('Y') > $year
|
||||
or (date('Y') == $year
|
||||
and date('m') >= $month)
|
||||
) and (
|
||||
$firstDate['Y'] < $year
|
||||
or $firstDate['Y'] == $year
|
||||
and $firstDate['m'] <= $month
|
||||
))
|
||||
<tr style='color:#ff0000'>
|
||||
<th>{{ startOfMonth($year, $month) }}</th>
|
||||
<th>Saldo</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th>{!! formatAmount($sums[$month - 1]['balance']) !!}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@endif
|
||||
@if (isset($bookings[$month]))
|
||||
@foreach($bookings[$month] as $booking)
|
||||
<tr>
|
||||
<td>{{ formatDate($booking->date) }}</td>
|
||||
<td>{{ $booking->reference }}</td>
|
||||
<td>{{ $booking->person_or_company }}</td>
|
||||
<td align='right'>
|
||||
@if ($booking->signedAmount() < 0)
|
||||
{!! formatAmount($booking->signedAmount()) !!}
|
||||
@endif
|
||||
</td>
|
||||
<td align='right'>
|
||||
@if ($booking->signedAmount() >= 0)
|
||||
{!! formatAmount($booking->signedAmount()) !!}
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@if ($booking->isSimple())
|
||||
{{ $booking->accountType()->number }}
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@if (!$booking->isSimple())
|
||||
@foreach ($booking->subBookings as $subBooking)
|
||||
<tr style='font-style:italic'>
|
||||
<td></td>
|
||||
<td>{{ $subBooking->reference }}</td>
|
||||
<td></td>
|
||||
<td align='right'>
|
||||
@if ($subBooking->signedAmount() < 0)
|
||||
{!! formatAmount($subBooking->signedAmount()) !!}
|
||||
@endif
|
||||
</td>
|
||||
<td align='right'>
|
||||
@if ($subBooking->signedAmount() >= 0)
|
||||
{!! formatAmount($subBooking->signedAmount()) !!}
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
{{ $subBooking->accountType->number }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@if ((
|
||||
date('Y') > $year
|
||||
or (date('Y') == $year
|
||||
and date('m') >= $month)
|
||||
) and (
|
||||
$firstDate['Y'] < $year
|
||||
or $firstDate['Y'] == $year
|
||||
and $firstDate['m'] <= $month
|
||||
))
|
||||
<tr style='color:#000080'>
|
||||
<th>
|
||||
{{ endOfMonth($year, $month) }}
|
||||
</th>
|
||||
<th>Monatsabschluss</th>
|
||||
<th></th>
|
||||
<th>{!! formatAmount($sums[$month]['expeditures']) !!}</th>
|
||||
<th>{!! formatAmount($sums[$month]['incomes']) !!}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr style='color:#ff0000'>
|
||||
<th>
|
||||
{{ endOfMonth($year, $month) }}
|
||||
</th>
|
||||
<th>Saldo</th>
|
||||
<th></th>
|
||||
<th>{!! formatAmount($sums[$month]['balance']) !!}</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@endif
|
||||
</table>
|
||||
@endfor
|
||||
@endsection
|
||||
@@ -2,13 +2,17 @@
|
||||
|
||||
@section('subnav')
|
||||
<li class="nav-item">
|
||||
<a href="{{ url()->previous() }}" class="btn btn-outline-primary">Zurück</a>
|
||||
<a href="{{ url()->previous() }}" class="btn btn-outline-secondary">Zurück</a>
|
||||
</li>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<h1>@yield('title')</h1>
|
||||
<form action="/people/@if (!is_null($person->id)) {{ $person->id }} @endif" method='post'>
|
||||
@if (is_null($person->id))
|
||||
<form action='/people' method='post'>
|
||||
@else
|
||||
<form action='/people/{{ $person->id }}' method='post'>
|
||||
@endif
|
||||
@if (!is_null($person->id))
|
||||
{{ method_field('patch') }}
|
||||
@endif
|
||||
@@ -125,8 +129,24 @@
|
||||
{{-- Create empty input field for a new member state record. --}}
|
||||
@if (!$person->isMember())
|
||||
<tr>
|
||||
<td>{{ Form::date('memberState[0][joining_date]') }}</td>
|
||||
<td>{{ Form::date('memberState[0][leaving_date]') }}</td>
|
||||
<td>
|
||||
{{
|
||||
Form::date(
|
||||
'memberState[0][joining_date]',
|
||||
null,
|
||||
['class' => 'form-control']
|
||||
)
|
||||
}}
|
||||
</td>
|
||||
<td>
|
||||
{{
|
||||
Form::date(
|
||||
'memberState[0][leaving_date]',
|
||||
null,
|
||||
['class' => 'form-control']
|
||||
)
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</table>
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
|
||||
@section('content')
|
||||
<h1>@yield('title')</h1>
|
||||
<form action="/targets/@if (!is_null($personTarget->id)) {{ $personTarget->id }} @endif" method='post'>
|
||||
@if (is_null($personTarget->id))
|
||||
<form action='/targets' method='post'>
|
||||
@else
|
||||
<form action='/targets/{{ $personTarget->id }}' method='post'>
|
||||
@endif
|
||||
@if (!is_null($personTarget->id))
|
||||
{{ method_field('patch') }}
|
||||
@endif
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
@extends('layout.master')
|
||||
|
||||
@section('subnav')
|
||||
<a href='{{ url()->previous() }}'>Zurück</a>
|
||||
<a href='{{ url()->previous() }}' class='btn btn-outline-secondary'>Zurück</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<h3>@yield('title')</h3>
|
||||
<form action="/projects/@if (!is_null($project->id)) {{ $project->id }} @endif" method='post'>
|
||||
@if (is_null($project->id))
|
||||
<form action='/projects' method='post'>
|
||||
@else
|
||||
<form action='/projects/{{$project->id}}' method='post'>
|
||||
@endif
|
||||
@if (!is_null($project->id))
|
||||
{{ method_field('patch') }}
|
||||
@endif
|
||||
|
||||
@@ -68,7 +68,5 @@
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Twäng! e. V. - @yield('title')</title>
|
||||
|
||||
<link rel="stylesheet"
|
||||
href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
|
||||
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
|
||||
crossorigin="anonymous">
|
||||
|
||||
<style>
|
||||
body {
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@yield('content')
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
@section('subnav')
|
||||
<li class="nav-item">
|
||||
<a href="{{ url()->previous() }}" class="btn btn-outline-primary">Zurück</a>
|
||||
<a href="{{ url()->previous() }}" class="btn btn-outline-secondary">Zurück</a>
|
||||
</li>
|
||||
@endsection
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
@if ($person->isEven())
|
||||
<div class="alert alert-danger">
|
||||
<p>Soll <b>{{ $person->fullName() }}</b> wirklich gelöscht werden?</p>
|
||||
<button type="submit" id="submit">Ja</button>
|
||||
<button class='btn btn-primary' type="submit" id="submit">Ja</button>
|
||||
<a href="{{ url()->previous() }}" class="btn btn-outline-secondary">Nein</a>
|
||||
</div>
|
||||
@else
|
||||
<div class="alert alert-warning">
|
||||
|
||||
@@ -3,32 +3,35 @@
|
||||
@section('title', 'Zahlungsverflichtung löschen')
|
||||
|
||||
@section('subnav')
|
||||
<a href='{{ url()->previous() }}'>Zurück</a>
|
||||
<a href='{{ url()->previous() }}' class='btn btn-outline-secondary'>Zurück</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<h2>@yield('title')</h2>
|
||||
<form action='/targets/{{ $personTarget->id }}' method='post'>
|
||||
<form action='/targets/{{ $personTarget->id }}' method='post' class='mt-4 text-center'>
|
||||
{{ method_field('delete') }}
|
||||
{{ csrf_field() }}
|
||||
<p>Soll folgende Zahlungsverpflichtung wirklich gelöscht werden?</p>
|
||||
<div class='alert alert-danger'>
|
||||
<p>Soll folgende Zahlungsverpflichtung wirklich gelöscht werden?</p>
|
||||
|
||||
<table border='1'>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Position</th>
|
||||
<th>Person / Firma</th>
|
||||
<th>Betrag</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ formatDate($personTarget->date) }}</td>
|
||||
<td>{{ $personTarget->reference }}</td>
|
||||
<td>{{ $personTarget->person->fullName() }}</td>
|
||||
<td>{{ $personTarget->signedAmount() }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class='table'>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Position</th>
|
||||
<th>Person / Firma</th>
|
||||
<th>Betrag</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ formatDate($personTarget->date) }}</td>
|
||||
<td>{{ $personTarget->reference }}</td>
|
||||
<td>{{ $personTarget->person->fullName() }}</td>
|
||||
<td>{!! formatAmount($personTarget->signedAmount()) !!}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<button type="submit" id="submit">Ja</button>
|
||||
<button class='btn btn-primary' type="submit" id="submit">Ja</button>
|
||||
<a href="{{ url()->previous() }}" class="btn btn-outline-secondary">Nein</a>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
@section('title', 'Forderungen und Verbindlichkeiten')
|
||||
|
||||
@section('subnav')
|
||||
<a href='/targets/create' class='btn btn-outline-success'>Neue Forderung / Verbindlichkeit</a>
|
||||
<li class='nav-item'>
|
||||
<a href='/targets/create' class='btn btn-outline-success'>Neue Forderung / Verbindlichkeit</a>
|
||||
</li>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
@@ -17,7 +19,7 @@
|
||||
<th>Soll</th>
|
||||
<th>Ist</th>
|
||||
<th>Differenz</th>
|
||||
<th>Aktion</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
@@ -37,9 +39,21 @@
|
||||
<td>{!! formatAmount($personTarget->actualsSum()) !!}</td>
|
||||
<td>{!! formatAmount($personTarget->difference()) !!}</td>
|
||||
<td>
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<a href='/targets/{{ $personTarget->id }}/edit' class="btn btn-success"><i class="fas fa-edit"></i></a>
|
||||
<a href='/targets/{{ $personTarget->id }}/delete' class="btn btn-danger"><i class="fas fa-trash"></i></a>
|
||||
<div class="btn-group" role="group">
|
||||
<a href='/targets/{{ $personTarget->id }}/edit'
|
||||
class='btn btn-success'
|
||||
data-toggle='tooltip'
|
||||
data-placement='bottom'
|
||||
title='Bearbeiten'>
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<a href='/targets/{{ $personTarget->id }}/delete'
|
||||
class='btn btn-danger'
|
||||
data-toggle='tooltip'
|
||||
data-placement='bottom'
|
||||
title='Löschen'>
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -75,8 +89,20 @@
|
||||
<td>{!! formatAmount($personTarget->difference()) !!}</td>
|
||||
<td>
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<a href='/targets/{{ $personTarget->id }}/edit' class="btn btn-success"><i class="fas fa-edit"></i></a>
|
||||
<a href='/targets/{{ $personTarget->id }}/delete' class="btn btn-danger"><i class="fas fa-trash"></i></a>
|
||||
<a href='/targets/{{ $personTarget->id }}/edit'
|
||||
class='btn btn-success'
|
||||
data-toggle='tooltip'
|
||||
data-placement='bottom'
|
||||
title='Bearbeiten'>
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<a href='/targets/{{ $personTarget->id }}/delete'
|
||||
class='btn btn-danger'
|
||||
data-toggle='tooltip'
|
||||
data-placement='bottom'
|
||||
title='Löschen'>
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -3,16 +3,21 @@
|
||||
@section('title', 'Projekt löschen')
|
||||
|
||||
@section('subnav')
|
||||
<a href='{{ url()->previous() }}'>Zurück</a>
|
||||
<a href='{{ url()->previous() }}' class='btn btn-outline-secondary'>Zurück</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<form action='/projects/{{ $project->id }}' method='post'>
|
||||
<form action='/projects/{{ $project->id }}' method='post' class='mt-4 text-center'>
|
||||
{{ method_field('delete') }}
|
||||
{{ csrf_field() }}
|
||||
<p>Soll das Projekt "<b>{{ $project->name }}</b>" wirklich gelöscht
|
||||
werden?</p>
|
||||
<button type="submit" id="submit">Ja</button>
|
||||
<div class='alert alert-danger'>
|
||||
<p>
|
||||
Soll das Projekt <b>{{ $project->name }}</b> wirklich
|
||||
gelöscht werden?
|
||||
</p>
|
||||
<button class='btn btn-primary' type="submit" id="submit">Ja</button>
|
||||
<a href="{{ url()->previous() }}" class="btn btn-outline-secondary">Nein</a>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
<td>{{ $project->name }}</td>
|
||||
<td>{{ formatDate($project->start_date) }}</td>
|
||||
<td>{{ formatDate($project->end_date) }}</td>
|
||||
<td width="1">
|
||||
<td>
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<a href='/projects/{{ $project->id }}/edit'
|
||||
class="btn btn-success"
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
@extends('layout.print')
|
||||
|
||||
@section('title', 'Abrechnung ' . $year)
|
||||
|
||||
@section('content')
|
||||
<table class='table table-sm table-borderless'>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Kontostand am 1. 1. {{ $year }}</b>
|
||||
</td>
|
||||
<td>
|
||||
<b>{!! formatAmount($startBalance) !!}</b>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td colspan='2'></td></tr>
|
||||
@foreach($scopes as $scope)
|
||||
<tr>
|
||||
<td colspan='2'><b>{{ $scope->name }}</b></td>
|
||||
</tr>
|
||||
@foreach($scope->accountClasses as $accountClass)
|
||||
<tr>
|
||||
<td colspan='2' style='text-indent: 2em;'>
|
||||
<u>{{ $accountClass->name }}</u>
|
||||
</td>
|
||||
</tr>
|
||||
@foreach($accountClass->accountTypes as $accountType)
|
||||
<tr>
|
||||
<td style='text-indent: 4em;'>
|
||||
{{$accountType->number}} - {{$accountType->name}}
|
||||
</td>
|
||||
<td>
|
||||
{!! formatAmount($accountType->subBookings->sum('amount')) !!}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
<tr><td colspan='2'></td></tr>
|
||||
@endforeach
|
||||
<tr>
|
||||
<td colspan='2' style='text-indent: 2em;'>
|
||||
<u>GESAMT</u>
|
||||
</td>
|
||||
<tr>
|
||||
@foreach($scope->accountClasses as $accountClass)
|
||||
<tr>
|
||||
<td style='text-indent: 4em;'>
|
||||
{{ $accountClass->name }}
|
||||
</td>
|
||||
<td>
|
||||
{!! formatAmount($accountClass->amount) !!}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
<tr>
|
||||
<td style='text-indent: 4em;'>
|
||||
Saldo {{ $scope->name }}
|
||||
</td>
|
||||
<td>{!! formatAmount($scope->balance) !!}</td>
|
||||
</tr>
|
||||
<tr><td colspan='2'></td></tr>
|
||||
@endforeach
|
||||
<tr>
|
||||
<td colspan='2'>
|
||||
<b>Übersicht</b>
|
||||
</td>
|
||||
<tr>
|
||||
@foreach($scopes as $scope)
|
||||
<tr>
|
||||
<td style='text-indent: 4em;'>
|
||||
Saldo {{ $scope->name }}
|
||||
</td>
|
||||
<td>{!! formatAmount($scope->balance) !!}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
<tr>
|
||||
<td style='text-indent: 4em;'>Gesamtsaldo</td>
|
||||
<td>{!! formatAmount($scopes->sum('balance')) !!}</td>
|
||||
</tr>
|
||||
<tr><td colspan='2'></td></tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Kontostand am 31. 12. {{ $year }}</b>
|
||||
</td>
|
||||
<td>
|
||||
<b>{!! formatAmount($endBalance) !!}</b>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@endsection
|
||||
@@ -0,0 +1,48 @@
|
||||
@extends('layout.master')
|
||||
|
||||
@section('title', 'Buchungen nach Konten ' . $year)
|
||||
|
||||
@section('subnav')
|
||||
<a class='btn btn-outline-secondary' href='/bookings/year-{{ $year }}'>
|
||||
Zurück
|
||||
</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<h2>@yield('title')</h2>
|
||||
@foreach($scopes as $scope)
|
||||
<h3>{{ $scope->name }}</h3>
|
||||
@foreach($scope->accountClasses as $accountClass)
|
||||
<h4>{{ $accountClass->name }}</h4>
|
||||
<table class='table'>
|
||||
<tr style='color: #000080'>
|
||||
<th>Datum</th>
|
||||
<th>Position</th>
|
||||
<th>Person / Firma</th>
|
||||
<th>Betrag</th>
|
||||
</td>
|
||||
@foreach($accountClass->accountTypes as $accountType)
|
||||
<tr>
|
||||
<th colspan='4' style='color: #000080'>
|
||||
{{ $accountType->number . ' - ' . $accountType->name }}
|
||||
</th>
|
||||
</tr>
|
||||
@foreach($accountType->subBookings as $subBooking)
|
||||
<tr>
|
||||
<td>{{ formatDate($subBooking->date()) }}</td>
|
||||
<td>{{ $subBooking->reference }}</td>
|
||||
<td>{{ $subBooking->personOrCompany() }}</td>
|
||||
<td>{!! formatAmount($subBooking->amount) !!}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
<tr>
|
||||
<th colspan='4' style='text-align: right; color:#ff0000'>
|
||||
{!! formatAmount($accountType->subBookings
|
||||
->sum('amount')) !!}
|
||||
</th>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
@endforeach
|
||||
@endforeach
|
||||
@endsection
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
@extends('layout.print')
|
||||
|
||||
@section('title', 'Buchungen nach Konten ' . $year)
|
||||
|
||||
@section('content')
|
||||
@foreach($scopes as $scope)
|
||||
@foreach($scope->accountClasses as $accountClass)
|
||||
<h5>{{ $scope->name }}</h5>
|
||||
<b>{{ $accountClass->name }}</b>
|
||||
<table class='table table-sm table-borderless' style='page-break-after: always'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Position</th>
|
||||
<th>Person / Firma</th>
|
||||
<th>Betrag</th>
|
||||
</td>
|
||||
</thead>
|
||||
@foreach($accountClass->accountTypes as $accountType)
|
||||
<tr>
|
||||
<th colspan='4' style='color: #000080'>
|
||||
{{ $accountType->number . ' - ' . $accountType->name }}
|
||||
</th>
|
||||
</tr>
|
||||
@foreach($accountType->subBookings as $subBooking)
|
||||
<tr>
|
||||
<td>{{ formatDate($subBooking->date()) }}</td>
|
||||
<td>{{ $subBooking->reference }}</td>
|
||||
<td>{{ $subBooking->personOrCompany() }}</td>
|
||||
<td>{!! formatAmount($subBooking->amount) !!}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
<tr>
|
||||
<th colspan='4' style='text-align: right; color:#ff0000'>
|
||||
{!! formatAmount($accountType->subBookings
|
||||
->sum('amount')) !!}
|
||||
</th>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
@endforeach
|
||||
@endforeach
|
||||
@endsection
|
||||
+13
-11
@@ -19,52 +19,53 @@ Route::middleware(['auth'])->group(function() {
|
||||
**************************************************************************/
|
||||
Route::get('/people', 'PeopleController@index');
|
||||
Route::post('/people', 'PeopleController@store');
|
||||
|
||||
|
||||
Route::get('/people/create', 'PeopleController@create');
|
||||
Route::get('/people/{person}', 'PeopleController@show');
|
||||
Route::patch('/people/{person}', 'PeopleController@update');
|
||||
Route::delete('/people/{person}', 'PeopleController@destroy');
|
||||
|
||||
|
||||
Route::get('/people/{person}/edit', 'PeopleController@edit');
|
||||
Route::get('/people/{person}/delete', 'PeopleController@delete');
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* BOOKINGS *
|
||||
**************************************************************************/
|
||||
Route::redirect('/bookings', 'bookings/year-' . date('Y'));
|
||||
Route::get('/bookings/year-{year}', 'BookingsController@index');
|
||||
Route::get('/bookings/year-{year}/print', 'BookingsController@report');
|
||||
Route::post('/bookings', 'BookingsController@store');
|
||||
|
||||
|
||||
Route::get('/bookings/create', 'BookingsController@create');
|
||||
Route::patch('/bookings/{booking}', 'BookingsController@update');
|
||||
Route::delete('/bookings/{booking}', 'BookingsController@destroy');
|
||||
|
||||
|
||||
Route::get('/bookings/{booking}/edit', 'BookingsController@edit');
|
||||
Route::get('/bookings/{booking}/delete', 'BookingsController@delete');
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* PROJECTS *
|
||||
**************************************************************************/
|
||||
Route::get('/projects', 'ProjectsController@index');
|
||||
Route::post('/projects', 'ProjectsController@store');
|
||||
|
||||
|
||||
Route::get('/projects/create', 'ProjectsController@create');
|
||||
Route::patch('/projects/{project}', 'ProjectsController@update');
|
||||
Route::delete('/projects/{project}', 'ProjectsController@destroy');
|
||||
|
||||
|
||||
Route::get('/projects/{project}/edit', 'ProjectsController@edit');
|
||||
Route::get('/projects/{project}/delete', 'ProjectsController@delete');
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* PERSON TARGETS *
|
||||
**************************************************************************/
|
||||
Route::get('/targets', 'PersonTargetsController@index');
|
||||
Route::post('/targets', 'PersonTargetsController@store');
|
||||
|
||||
|
||||
Route::get('/targets/create', 'PersonTargetsController@create');
|
||||
Route::patch('/targets/{personTarget}', 'PersonTargetsController@update');
|
||||
Route::delete('/targets/{personTarget}', 'PersonTargetsController@destroy');
|
||||
|
||||
|
||||
Route::get('/targets/{personTarget}/edit', 'PersonTargetsController@edit');
|
||||
Route::get('/targets/{personTarget}/delete', 'PersonTargetsController@delete');
|
||||
|
||||
@@ -74,6 +75,7 @@ Route::middleware(['auth'])->group(function() {
|
||||
Route::get('/reports/projects/{project}', 'ReportsController@project');
|
||||
Route::get('/reports/balances/{year}', 'ReportsController@balances');
|
||||
Route::get('/reports/scopes/{type}/{year}', 'ReportsController@scopes');
|
||||
Route::get('/reports/scopes/{type}/{year}/print', 'ReportsController@printScopes');
|
||||
Route::get('/reports/targets/', 'ReportsController@targets');
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Laravel 5.6's PackageManifest predates Composer 2. Composer 2 stores the
|
||||
* installed package list under a "packages" key, which makes Laravel's
|
||||
* package:discover command fail with "Undefined index: name".
|
||||
*
|
||||
* This script adds support for both formats to the vendored framework file.
|
||||
* Composer runs it before package:discover, so it is safe to run repeatedly.
|
||||
*/
|
||||
|
||||
$file = __DIR__.'/../vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php';
|
||||
|
||||
if (! file_exists($file)) {
|
||||
fwrite(STDERR, "PackageManifest.php not found; skipping Composer 2 patch.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
$contents = file_get_contents($file);
|
||||
|
||||
if (strpos($contents, "\$packages = \$packages['packages'] ?? \$packages;") !== false) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
$needle = '$packages = json_decode($this->files->get($path), true);';
|
||||
$replacement = $needle."\n\n \$packages = \$packages['packages'] ?? \$packages;";
|
||||
|
||||
if (strpos($contents, $needle) === false) {
|
||||
fwrite(STDERR, "Could not find PackageManifest build() snippet; skipping patch.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
file_put_contents($file, str_replace($needle, $replacement, $contents));
|
||||
@@ -16,6 +16,6 @@ class ExampleTest extends TestCase
|
||||
{
|
||||
$response = $this->get('/');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertRedirect('/bookings');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user