Compare commits
27 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c65549dde7 | ||
|
|
46167d600c | ||
|
|
7091fcf23c | ||
|
|
c0fe0dd959 | ||
|
|
8b637f7b13 | ||
|
|
1fd09c6bec | ||
|
|
ce6fcd7f83 | ||
|
|
ab7b627cbc | ||
|
|
a33132e1d4 | ||
|
|
40491b451f | ||
|
|
5efb26e952 | ||
|
|
8941c7ec81 | ||
|
|
8a2700c554 | ||
|
|
88e5379610 | ||
|
|
86aa480c04 | ||
|
|
b5663d19ce | ||
|
|
847a543dab | ||
|
|
de29cda24f | ||
|
|
b1f0f0c885 | ||
|
|
8a607030a4 | ||
|
|
0a7f27d221 | ||
|
|
45bc580c1e | ||
|
|
138c0ef2f2 | ||
|
|
f25b458c97 | ||
|
|
9dc1aa728e | ||
|
|
18f104ae80 | ||
|
|
f4490e18d7 |
164 changed files with 13806 additions and 6494 deletions
41
.eslintrc.json
Normal file
41
.eslintrc.json
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:vue/vue3-strongly-recommended",
|
||||
"@vue/eslint-config-typescript"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.vue"],
|
||||
"rules": {
|
||||
"no-undef": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.vue"],
|
||||
"rules": {
|
||||
"indent": "off"
|
||||
}
|
||||
}
|
||||
],
|
||||
"parser": "vue-eslint-parser",
|
||||
"parserOptions": {
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": ["vue", "@typescript-eslint"],
|
||||
"ignorePatterns": ["webpack.mix.js", "**/vendor/*.js", "**/vendor/**/*.js"],
|
||||
"rules": {
|
||||
"indent": ["error", 4, { "SwitchCase": 1 }],
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"quotes": ["error", "double"],
|
||||
"semi": ["error", "always"],
|
||||
"vue/script-indent": ["error", 2, { "baseIndent": 0 }],
|
||||
"vue/one-component-per-file": "off"
|
||||
}
|
||||
}
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -18,3 +18,4 @@ yarn-error.log
|
|||
package-lock.json
|
||||
composer.lock
|
||||
.idea/
|
||||
auth.json
|
||||
24
.stylelintrc.json
Normal file
24
.stylelintrc.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"extends": [
|
||||
"stylelint-config-sass-guidelines",
|
||||
"stylelint-config-idiomatic-order"
|
||||
],
|
||||
"ignoreFiles": [
|
||||
"**/vendor/*.css",
|
||||
"**/vendor/**/*.css",
|
||||
"**/vendor/*.scss",
|
||||
"**/vendor/**/*.scss",
|
||||
"**/vendor/*.sass",
|
||||
"**/vendor/**/*.sass",
|
||||
"**/vendor/*.less",
|
||||
"**/vendor/**/*.less"
|
||||
],
|
||||
"customSyntax": "postcss-scss",
|
||||
"rules": {
|
||||
"indentation": 4,
|
||||
"string-quotes": "double",
|
||||
"selector-max-id": null,
|
||||
"color-no-invalid-hex": true,
|
||||
"order/properties-alphabetical-order": null
|
||||
}
|
||||
}
|
||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -1,12 +1,13 @@
|
|||
{
|
||||
"workbench.colorCustomizations": {
|
||||
"activityBar.activeBackground": "#3371a9",
|
||||
"activityBar.activeBorder": "#621e41",
|
||||
"activityBar.activeBackground": "#3371a9",
|
||||
"activityBar.background": "#3371a9",
|
||||
"activityBar.foreground": "#e7e7e7",
|
||||
"activityBar.inactiveForeground": "#e7e7e799",
|
||||
"activityBarBadge.background": "#621e41",
|
||||
"activityBarBadge.foreground": "#e7e7e7",
|
||||
"commandCenter.border": "#e7e7e799",
|
||||
"sash.hoverBorder": "#3371a9",
|
||||
"statusBar.background": "#275782",
|
||||
"statusBar.foreground": "#e7e7e7",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ use App\Enums\Role;
|
|||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class CreateUser extends Command
|
||||
{
|
||||
|
|
@ -30,19 +32,57 @@ class CreateUser extends Command
|
|||
*/
|
||||
public function handle()
|
||||
{
|
||||
$name = $this->ask('What is the name?');
|
||||
$email = $this->ask('What is the email?');
|
||||
$pwd = $this->secret('What is the password?');
|
||||
$user = new User();
|
||||
$user->name = $name;
|
||||
$user->email = $email;
|
||||
if ($this->confirm('Is the user an admin?')) {
|
||||
$user->role = Role::admin();
|
||||
} else {
|
||||
$user->role = Role::client();
|
||||
$email = null;
|
||||
while (is_null($email)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user email', 'equipe.web@ldc.fr');
|
||||
$validator = Validator::make(['email' => $tmp], [
|
||||
'email' => 'required|unique:users,email|email:rfc,dns'
|
||||
]);
|
||||
$validator->validate();
|
||||
$email = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid email %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$user->password = Hash::make($pwd);
|
||||
$user->save();
|
||||
$name = null;
|
||||
while (is_null($name)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user name', 'Admin');
|
||||
$validator = Validator::make(['name' => $tmp], [
|
||||
'name' => 'required|min:5,max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$name = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid name %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$password = null;
|
||||
while (
|
||||
($password = $this->secret(
|
||||
(!\is_null($password) ? 'Failed to confirm, ' : '') . 'Type the wanted user password'
|
||||
)) !== $this->secret('Confirm the password')
|
||||
) {
|
||||
continue;
|
||||
};
|
||||
|
||||
|
||||
$user = new User();
|
||||
$user->name = $name;
|
||||
$user->email = $email;
|
||||
$user->role = $this->confirm('Is the user an admin?') ? Role::admin() : Role::client();
|
||||
$user->password = Hash::make($password);
|
||||
$user->saveOrFail();
|
||||
|
||||
$this->info('User created.');
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,77 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/*
|
||||
* Command Name: LDC Web Status Checker
|
||||
* Description: Envoi des infos Serveur/Laravel vers LDC Web
|
||||
* Version: 1.1
|
||||
* Author: Vincent BRIDIER
|
||||
* Author URI: vincent.bridier@ldc.fr
|
||||
*/
|
||||
|
||||
class LdcWebStatusChecker extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'ldcweb:statuschecker';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Envoi des infos Serveur/Laravel vers LDC Web';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$data = [];
|
||||
$data['uuid'] = config('ldcweb.project_uuid');
|
||||
|
||||
// Sitemap.xml ?
|
||||
if (file_exists(public_path() . '/sitemap.xml')) {
|
||||
$data['sitemap'] = 'true';
|
||||
} else {
|
||||
$data['sitemap'] = 'false';
|
||||
}
|
||||
|
||||
// Robots.txt ?
|
||||
if (file_exists(public_path() . '/robots.txt')) {
|
||||
$data['robots'] = 'true';
|
||||
} else {
|
||||
$data['robots'] = 'false';
|
||||
}
|
||||
|
||||
// Check logs
|
||||
$data['logs'] = 0;
|
||||
$patherror = storage_path('/logs');
|
||||
$files = glob($patherror . '/*.log');
|
||||
if (count($files) > 0) {
|
||||
foreach ($files as $file) {
|
||||
$data['logs'] = $data['logs'] + filesize($file);
|
||||
}
|
||||
}
|
||||
|
||||
$data['code']['version'] = app()->version();
|
||||
|
||||
// Send by cURL
|
||||
$url = 'https://ldc-web.ldc.fr/api/status-checker';
|
||||
$ch = curl_init($url);
|
||||
$payload = ['token' => 'CE8S52Qq7stf5k8frF4T', 'datas' => json_encode($data)];
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,9 +12,13 @@ use Kwaadpepper\Enum\BaseEnumRoutable;
|
|||
* @method static self informations()
|
||||
* @method static self feedback()
|
||||
*/
|
||||
|
||||
class FileCategory extends BaseEnumRoutable
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
|
|
@ -27,6 +31,11 @@ class FileCategory extends BaseEnumRoutable
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -8,9 +8,13 @@ use Kwaadpepper\Enum\BaseEnumRoutable;
|
|||
* @method static self stringlink()
|
||||
* @method static self binfile()
|
||||
*/
|
||||
|
||||
class FileType extends BaseEnumRoutable
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
|
|
@ -19,6 +23,11 @@ class FileType extends BaseEnumRoutable
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
|||
73
app/Enums/Invoice/TaskType.php
Normal file
73
app/Enums/Invoice/TaskType.php
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums\Invoice;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnumRoutable;
|
||||
|
||||
/**
|
||||
* @method static self web()
|
||||
* @method static self seo()
|
||||
* @method static self package()
|
||||
* @method static self arbitrary()
|
||||
*/
|
||||
class TaskType extends BaseEnumRoutable
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'web' => 1,
|
||||
'seo' => 2,
|
||||
'package' => 3,
|
||||
'arbitrary' => 4,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'web' => trans('Web'),
|
||||
'seo' => trans('SEO'),
|
||||
'package' => trans('Forfait'),
|
||||
'arbitrary' => trans('Libre'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum prices
|
||||
*
|
||||
* @return array<string,int>
|
||||
*/
|
||||
protected static function prices(): array
|
||||
{
|
||||
return [
|
||||
'web' => 460,
|
||||
'seo' => 690,
|
||||
// * Linked to packages table
|
||||
'package' => 0,
|
||||
// * Arbitrary number
|
||||
'arbitrary' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $attribute
|
||||
* @return integer|string
|
||||
*/
|
||||
public function __get(string $attribute)
|
||||
{
|
||||
if ($attribute === 'price') {
|
||||
return $this->prices()[$this->getDefinition()];
|
||||
}
|
||||
return parent::__get($attribute);
|
||||
}
|
||||
}
|
||||
|
|
@ -10,9 +10,13 @@ use Kwaadpepper\Enum\BaseEnumRoutable;
|
|||
* @method static self high()
|
||||
* @method static self overload()
|
||||
*/
|
||||
|
||||
class LoadLevel extends BaseEnumRoutable
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
|
|
@ -23,6 +27,11 @@ class LoadLevel extends BaseEnumRoutable
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ use Kwaadpepper\Enum\BaseEnumRoutable;
|
|||
*/
|
||||
class ActivityType extends BaseEnumRoutable
|
||||
{
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function labels()
|
||||
{
|
||||
return [
|
||||
|
|
@ -30,6 +35,11 @@ class ActivityType extends BaseEnumRoutable
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum colors
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function colors(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@ use Kwaadpepper\Enum\BaseEnumRoutable;
|
|||
*/
|
||||
class CellModel extends BaseEnumRoutable
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
|
|
@ -29,6 +34,11 @@ class CellModel extends BaseEnumRoutable
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ use Kwaadpepper\Enum\BaseEnumRoutable;
|
|||
*/
|
||||
class CellType extends BaseEnumRoutable
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
|
|
@ -29,6 +34,11 @@ class CellType extends BaseEnumRoutable
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ use Kwaadpepper\Enum\BaseEnumRoutable;
|
|||
*/
|
||||
class TableRow extends BaseEnumRoutable
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
|
|
@ -32,6 +37,11 @@ class TableRow extends BaseEnumRoutable
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ use App\Models\User;
|
|||
|
||||
class FileCreated extends Loggable
|
||||
{
|
||||
/** @var File */
|
||||
/** @var \App\Models\File */
|
||||
public $file;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \App\Models\File $file
|
||||
* @param \App\Models\User $user
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(File $file, User $user)
|
||||
|
|
|
|||
|
|
@ -11,14 +11,16 @@ abstract class Loggable
|
|||
use Dispatchable;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var User */
|
||||
/** @var \App\Models\User */
|
||||
public $user;
|
||||
|
||||
/** @var string */
|
||||
public $message = '';
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class NotifyAdmin
|
|||
use InteractsWithSockets;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var Ticket */
|
||||
/** @var \App\Models\Ticket */
|
||||
public $ticket;
|
||||
|
||||
/** @var string */
|
||||
|
|
@ -22,6 +22,8 @@ class NotifyAdmin
|
|||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @param string $corpsMaj
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Ticket $ticket, string $corpsMaj)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class NotifySubscriptions
|
|||
use InteractsWithSockets;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var Ticket */
|
||||
/** @var \App\Models\Ticket */
|
||||
public $ticket;
|
||||
|
||||
/** @var string */
|
||||
|
|
@ -26,6 +26,9 @@ class NotifySubscriptions
|
|||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @param string $corpsMaj
|
||||
* @param \Illuminate\Support\Collection|null $ignoreUsers
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Ticket $ticket, string $corpsMaj, Collection $ignoreUsers = null)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class NotifyTicketCreator
|
|||
use InteractsWithSockets;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var Ticket */
|
||||
/** @var \App\Models\Ticket */
|
||||
public $ticket;
|
||||
|
||||
/** @var string */
|
||||
|
|
@ -22,6 +22,8 @@ class NotifyTicketCreator
|
|||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @param string $corpsMaj
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Ticket $ticket, string $corpsMaj)
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ use App\Models\User;
|
|||
|
||||
class ProjectUpdated extends Loggable
|
||||
{
|
||||
/** @var Project */
|
||||
/** @var \App\Models\Project */
|
||||
public $project;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \App\Models\Project $project
|
||||
* @param \App\Models\User $user
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Project $project, User $user)
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ use App\Models\User;
|
|||
|
||||
class SiteUpdated extends Loggable
|
||||
{
|
||||
/** @var Site */
|
||||
/** @var \App\Models\Site */
|
||||
public $site;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \App\Models\Site $site
|
||||
* @param \App\Models\User $user
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Site $site, User $user)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Enums\TicketStatus;
|
||||
use App\Models\Ticket;
|
||||
use App\Models\User;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
|
|
@ -14,12 +15,13 @@ class TicketStatusChanged
|
|||
use InteractsWithSockets;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var Ticket */
|
||||
/** @var \App\Models\Site */
|
||||
public $ticket;
|
||||
|
||||
/** @var User */
|
||||
/** @var \App\Models\User */
|
||||
public $user;
|
||||
|
||||
/** @var \App\Enums\TicketStatus */
|
||||
public $status;
|
||||
|
||||
/** @var string */
|
||||
|
|
@ -28,9 +30,13 @@ class TicketStatusChanged
|
|||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @param \App\Enums\TicketStatus $status
|
||||
* @param \App\Models\User|null $user
|
||||
* @param string|null $message
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Ticket $ticket, $status, User $user = null, string $message = null)
|
||||
public function __construct(Ticket $ticket, TicketStatus $status, User $user = null, string $message = null)
|
||||
{
|
||||
$this->ticket = $ticket;
|
||||
$this->status = $status;
|
||||
|
|
|
|||
|
|
@ -8,16 +8,6 @@ use Illuminate\Foundation\Auth\ConfirmsPasswords;
|
|||
|
||||
class ConfirmPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Confirm Password Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password confirmations and
|
||||
| uses a simple trait to include the behavior. You're free to explore
|
||||
| this trait and override any functions that require customization.
|
||||
|
|
||||
*/
|
||||
use ConfirmsPasswords;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -7,18 +7,13 @@ use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
|||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset emails and
|
||||
| includes a trait which assists in sending these notifications from
|
||||
| your application to your users. Feel free to explore this trait.
|
||||
|
|
||||
*/
|
||||
use SendsPasswordResetEmails;
|
||||
|
||||
/**
|
||||
* ForgotPasswordController
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:web');
|
||||
|
|
|
|||
|
|
@ -8,16 +8,6 @@ use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
|||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles authenticating users for the application and
|
||||
| redirecting them to your home screen. The controller uses a trait
|
||||
| to conveniently provide its functionality to your applications.
|
||||
|
|
||||
*/
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -9,16 +9,6 @@ use Illuminate\Validation\Rules\Password;
|
|||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset requests
|
||||
| and uses a simple trait to include this behavior. You're free to
|
||||
| explore this trait and override any methods you wish to tweak.
|
||||
|
|
||||
*/
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
|
|
|
|||
22
app/Http/Controllers/CompanyController.php
Normal file
22
app/Http/Controllers/CompanyController.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Company;
|
||||
use Kwaadpepper\CrudPolicies\Traits\CrudController;
|
||||
|
||||
class CompanyController extends Controller
|
||||
{
|
||||
use CrudController;
|
||||
|
||||
/** @var \App\Models\MacroSchedule\Marker */
|
||||
public static $modelClass = Company::class;
|
||||
|
||||
/**
|
||||
* Crud Layout
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $layout = 'layout.app';
|
||||
}
|
||||
282
app/Http/Controllers/InvoiceController.php
Normal file
282
app/Http/Controllers/InvoiceController.php
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\Invoice\TaskType;
|
||||
use App\Http\Requests\Invoice\InvoiceSetDateRequest;
|
||||
use App\Models\Company;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Package;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Kwaadpepper\CrudPolicies\Http\Requests\CrudIndexRequest;
|
||||
use Kwaadpepper\CrudPolicies\Traits\CrudController;
|
||||
use Kwaadpepper\Enum\Rules\EnumIsValidRule;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* * Because update is denied when invoice is sent to the client
|
||||
* ForceUpdate On signed date
|
||||
* ForceUpdate On compta sent date
|
||||
*/
|
||||
class InvoiceController extends Controller
|
||||
{
|
||||
use CrudController {
|
||||
index as crudIndex;
|
||||
show as crudShow;
|
||||
create as crudCreate;
|
||||
edit as crudEdit;
|
||||
}
|
||||
|
||||
/** @var \App\Models\Invoice */
|
||||
public static $modelClass = Invoice::class;
|
||||
|
||||
/**
|
||||
* Crud Layout
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $layout = 'layout.app';
|
||||
|
||||
/**
|
||||
* Crud index view
|
||||
*
|
||||
* @param \Kwaadpepper\CrudPolicies\Http\Requests\CrudIndexRequest $request
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function index(CrudIndexRequest $request)
|
||||
{
|
||||
/** @var \Illuminate\View\View */
|
||||
$view = $this->crudIndex($request);
|
||||
if ($request->ajax()) {
|
||||
return $view;
|
||||
}
|
||||
if ($request->search and ($models = $view->getData()['models'])->count() === 1) {
|
||||
return \redirect()->route('invoices.edit', $models->first());
|
||||
}
|
||||
return view('invoices.index', $view->getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Index query middleware
|
||||
*
|
||||
* @param Builder $query
|
||||
* @return Builder
|
||||
* @throws \ErrorException If account is missing in url.
|
||||
*/
|
||||
public function indexQuery(Builder $query): Builder
|
||||
{
|
||||
$query->orderBy('created_at', 'DESC');
|
||||
|
||||
return $query->orWhere(function (Builder $q) {
|
||||
$q->whereHas('site', function ($q) {
|
||||
$q->where('name', 'LIKE', '%' . \filter_var(request()->search, \FILTER_SANITIZE_STRING) . '%');
|
||||
})->orWhereHas('company', function ($q) {
|
||||
$q->where('name', 'LIKE', '%' . \filter_var(request()->search, \FILTER_SANITIZE_STRING) . '%');
|
||||
})->orWhereHas('companyInvoiced', function ($q) {
|
||||
$q->where('name', 'LIKE', '%' . \filter_var(request()->search, \FILTER_SANITIZE_STRING) . '%');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show model action
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param mixed ...$params
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function show(Request $request, ...$params)
|
||||
{
|
||||
/** @var \Illuminate\View\View|\Illuminate\Http\JsonResponse */
|
||||
$view = call_user_func_array([$this, 'crudShow'], \array_merge([$request], $params));
|
||||
if ($view instanceof \Illuminate\Http\JsonResponse) {
|
||||
return $view;
|
||||
}
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Package> */
|
||||
$packages = Package::get()->keyBy('id')->all();
|
||||
return view('invoices.show', \array_merge($view->getData(), ['packages' => $packages]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Crud create view
|
||||
*
|
||||
* @param \Kwaadpepper\CrudPolicies\Http\Requests\CrudIndexRequest $request
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function create(CrudIndexRequest $request)
|
||||
{
|
||||
/** @var \Illuminate\View\View */
|
||||
$view = $this->crudCreate($request);
|
||||
|
||||
$companies = Company::get();
|
||||
$packages = Package::get();
|
||||
$taskRowModel = Invoice::getTaskStructure();
|
||||
|
||||
return view('invoices.create', \array_merge($view->getData(), [
|
||||
'companies' => $companies,
|
||||
'packages' => $packages,
|
||||
'taskRowModel' => $taskRowModel,
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Before store model middleware
|
||||
*
|
||||
* @param \App\Models\Invoice $model
|
||||
* @return void
|
||||
*/
|
||||
public function storeModel(Invoice &$model)
|
||||
{
|
||||
$this->validateTasks($model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Before update model middleware
|
||||
*
|
||||
* @param \App\Models\Invoice $model
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If invoice is signed.
|
||||
*/
|
||||
public function updateModel(Invoice &$model)
|
||||
{
|
||||
if ($model->signed_date) {
|
||||
throw ValidationException::withMessages(['erreur' => trans('Il n\'est pas possible de mettre a jour un devis qui est signé')
|
||||
]);
|
||||
}
|
||||
$this->validateTasks($model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit model action
|
||||
*
|
||||
* @param mixed ...$params
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function edit(...$params)
|
||||
{
|
||||
/** @var \Illuminate\View\View */
|
||||
$view = call_user_func_array([$this, 'crudEdit'], $params);
|
||||
|
||||
$companies = Company::get();
|
||||
$packages = Package::get();
|
||||
$taskRowModel = Invoice::getTaskStructure();
|
||||
|
||||
return view('invoices.edit', \array_merge($view->getData(), [
|
||||
'companies' => $companies,
|
||||
'packages' => $packages,
|
||||
'taskRowModel' => $taskRowModel,
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Tasks
|
||||
*
|
||||
* @param \App\Models\Invoice $invoice
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If tasks are not valid.
|
||||
*/
|
||||
private function validateTasks(Invoice $invoice): void
|
||||
{
|
||||
$tasks = \collect(\json_decode($invoice->tasks, true))
|
||||
->map(function ($task) {
|
||||
if (\is_array($task)) {
|
||||
return \array_intersect_key($task, Invoice::getTaskStructure());
|
||||
}
|
||||
});
|
||||
$invoice->tasks = Validator::make(['tasks' => $tasks->all()], [
|
||||
'tasks' => 'required|array|min:1',
|
||||
'tasks.*' => 'required|array',
|
||||
'tasks.*.days' => 'required|numeric|min:0.125',
|
||||
'tasks.*.amount' => 'required|numeric|min:0.125',
|
||||
'tasks.*.desc' => 'required|string|min:10',
|
||||
'tasks.*.type' => [
|
||||
'required', new EnumIsValidRule(TaskType::class)
|
||||
],
|
||||
'tasks.*.package' => 'required_if:tasks.*.type,' .
|
||||
TaskType::package()->value . '|nullable|exists:packages,id',
|
||||
], [], [
|
||||
'tasks' => trans('Tâches')
|
||||
])->validated()['tasks'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Download Invoice
|
||||
*
|
||||
* @param \App\Models\Invoice $invoice
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function download(Invoice $invoice): Response
|
||||
{
|
||||
$this->authorize($invoice, 'download');
|
||||
return $invoice->generateInvoice()
|
||||
->stream(Str::slug(trans('Devis :appname :date - ref :ref', [
|
||||
'appname' => config('app.name'),
|
||||
'date' => $invoice->created_at->isoFormat('YYYY-MM-DD'),
|
||||
'ref' => $invoice->ref,
|
||||
])) . '.pdf');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set signed date
|
||||
*
|
||||
* @param \App\Http\Requests\Invoice\InvoiceSetDateRequest $request
|
||||
* @param \App\Models\Invoice $invoice
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Validation\ValidationException If already signed.
|
||||
*/
|
||||
public function setSignedDate(InvoiceSetDateRequest $request, Invoice $invoice)
|
||||
{
|
||||
if ($invoice->signed_date) {
|
||||
throw ValidationException::withMessages([
|
||||
'erreur' => trans('La date de signature est déjà actée.')
|
||||
]);
|
||||
}
|
||||
$invoice->signed_date = $request->date;
|
||||
$invoice->saveOrFail();
|
||||
return \back()->with('success', trans('La date de signature à bien été enregistrée'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set client signed date
|
||||
*
|
||||
* @param \App\Http\Requests\Invoice\InvoiceSetDateRequest $request
|
||||
* @param \App\Models\Invoice $invoice
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Validation\ValidationException If already signed.
|
||||
*/
|
||||
public function setClientSentDate(InvoiceSetDateRequest $request, Invoice $invoice)
|
||||
{
|
||||
if ($invoice->sent_client_date) {
|
||||
throw ValidationException::withMessages([
|
||||
'erreur' => trans('La date de signature client est déjà actée.')
|
||||
]);
|
||||
}
|
||||
$invoice->sent_client_date = $request->date;
|
||||
$invoice->saveOrFail();
|
||||
return \back()->with('success', trans('La date de signature client à bien été enregistrée'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set compta signed date
|
||||
*
|
||||
* @param \App\Http\Requests\Invoice\InvoiceSetDateRequest $request
|
||||
* @param \App\Models\Invoice $invoice
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Validation\ValidationException If already signed.
|
||||
*/
|
||||
public function setComptaSentDate(InvoiceSetDateRequest $request, Invoice $invoice)
|
||||
{
|
||||
if ($invoice->sent_accounting_date) {
|
||||
throw ValidationException::withMessages([
|
||||
'erreur' => trans('La date de signature compta est déjà actée.')
|
||||
]);
|
||||
}
|
||||
$invoice->sent_accounting_date = $request->date;
|
||||
$invoice->saveOrFail();
|
||||
return \back()->with('success', trans('La date de signature compta à bien été enregistrée'));
|
||||
}
|
||||
}
|
||||
|
|
@ -16,8 +16,19 @@ class LogController extends Controller
|
|||
/** @var Log */
|
||||
public static $modelClass = Log::class;
|
||||
|
||||
/**
|
||||
* Crud Layout
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $layout = 'layout.app';
|
||||
|
||||
/**
|
||||
* Index query middleware
|
||||
*
|
||||
* @param Builder $query
|
||||
* @return Builder
|
||||
*/
|
||||
public function indexQuery(Builder $query): Builder
|
||||
{
|
||||
$parent = request()->site ?? request()->project;
|
||||
|
|
@ -29,9 +40,15 @@ class LogController extends Controller
|
|||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crud index view
|
||||
*
|
||||
* @param \Kwaadpepper\CrudPolicies\Http\Requests\CrudIndexRequest $request
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function index(CrudIndexRequest $request)
|
||||
{
|
||||
// Autosort
|
||||
// * Autosort
|
||||
if (!$request->sort_col and !$request->sort_way) {
|
||||
$request->merge([
|
||||
'sort_col' => 'created_at',
|
||||
|
|
@ -47,6 +64,12 @@ class LogController extends Controller
|
|||
return view('logs.index', $view->getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Before store model middleware
|
||||
*
|
||||
* @param \App\Models\Log $log
|
||||
* @return void
|
||||
*/
|
||||
public function storeModel(Log &$log)
|
||||
{
|
||||
$log->parent()->associate(request()->site ?? request()->project);
|
||||
|
|
|
|||
22
app/Http/Controllers/PackageController.php
Normal file
22
app/Http/Controllers/PackageController.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Package;
|
||||
use Kwaadpepper\CrudPolicies\Traits\CrudController;
|
||||
|
||||
class PackageController extends Controller
|
||||
{
|
||||
use CrudController;
|
||||
|
||||
/** @var \App\Models\MacroSchedule\Marker */
|
||||
public static $modelClass = Package::class;
|
||||
|
||||
/**
|
||||
* Crud Layout
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $layout = 'layout.app';
|
||||
}
|
||||
|
|
@ -13,6 +13,8 @@ use Illuminate\Database\Eloquent\Builder;
|
|||
/**
|
||||
* Alternate planner for Dev Team
|
||||
*
|
||||
* TODO: Refactor this controller.
|
||||
*
|
||||
* @author Olivier Legat <olivier.legat@ldc.fr>
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -402,10 +402,11 @@ class TicketController extends Controller
|
|||
*/
|
||||
public function reopen(Ticket $ticket)
|
||||
{
|
||||
$message = trans(':ticketName à réouvert le ticket n°:ticketNumber', [
|
||||
$message = trans(':ticketName à réouvert le ticket n°:ticketNumber', [
|
||||
'ticketName' => $ticket->user->name,
|
||||
'ticketNumber' => $ticket->id,
|
||||
]);
|
||||
/** @var \App\Enums\TicketStatus */
|
||||
$oldStatus = $ticket->status;
|
||||
$ticket->status = TicketStatus::inprogress();
|
||||
$ticket->saveQuietly();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ use App\Http\Controllers\Auth\ForgotPasswordController;
|
|||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Kwaadpepper\CrudPolicies\Traits\CrudController;
|
||||
|
||||
class UserController extends Controller
|
||||
|
|
@ -15,6 +14,9 @@ class UserController extends Controller
|
|||
__construct as __CrudConstructor;
|
||||
}
|
||||
|
||||
/**
|
||||
* UserController
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
|
@ -25,8 +27,19 @@ class UserController extends Controller
|
|||
/** @var User */
|
||||
public static $modelClass = User::class;
|
||||
|
||||
/**
|
||||
* Crud Layout
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $layout = 'layout.app';
|
||||
|
||||
/**
|
||||
* After store model middleware
|
||||
*
|
||||
* @param Model $model
|
||||
* @return void
|
||||
*/
|
||||
public function storedModel(Model &$model)
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
|
|
@ -34,11 +47,21 @@ class UserController extends Controller
|
|||
$model->sendMailConfirm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Password reset form
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function passwordReset()
|
||||
{
|
||||
return view('users.passwordReset');
|
||||
}
|
||||
|
||||
/**
|
||||
* Password reset submit
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function passwordResetSubmit()
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
|
|
@ -47,12 +70,21 @@ class UserController extends Controller
|
|||
return app(ForgotPasswordController::class)->sendResetLinkEmail($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show stats
|
||||
*
|
||||
* TODO: refator this using carbon.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function stats()
|
||||
{
|
||||
$user = Auth::user();
|
||||
$stats = [];
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
$stats = [];
|
||||
$curYear = date('Y');
|
||||
|
||||
for ($i = 2021; $i <= date('Y'); $i++) {
|
||||
for ($i = 2021; $i <= $curYear; $i++) {
|
||||
$start = $i . '-03-01';
|
||||
$end = $i + 1 . '-02-' . $this->getLastDayFebruary($i + 1);
|
||||
|
||||
|
|
@ -68,7 +100,13 @@ class UserController extends Controller
|
|||
return view('users.stats', ['stats' => array_reverse($stats)]);
|
||||
}
|
||||
|
||||
private function getLastDayFebruary($year)
|
||||
/**
|
||||
* Get february last day date of the year
|
||||
*
|
||||
* @param integer $year
|
||||
* @return integer 28 or 29
|
||||
*/
|
||||
private function getLastDayFebruary(int $year): int
|
||||
{
|
||||
if ((is_int($year / 4) && !is_int($year / 100)) || is_int($year / 400)) {
|
||||
return 29;
|
||||
|
|
|
|||
33
app/Http/Requests/Invoice/InvoiceSetDateRequest.php
Normal file
33
app/Http/Requests/Invoice/InvoiceSetDateRequest.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Invoice;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class InvoiceSetDateRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
/** @var \App\Models\User|null $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return auth()->check() && $user->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'date' => 'required|date'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ class SetCellContentRequest extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
$this->merge([
|
||||
'model' => $this->model ?? null,
|
||||
|
|
@ -30,7 +30,7 @@ class SetCellContentRequest extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'id' => 'required|exists:week_plannings,id',
|
||||
|
|
@ -52,7 +52,12 @@ class SetCellContentRequest extends FormRequest
|
|||
];
|
||||
}
|
||||
|
||||
public function attributes()
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'cellModel' => 'Type d\'élément lié',
|
||||
|
|
|
|||
|
|
@ -70,9 +70,11 @@ class StoreScheduleRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'activity' => trans('catégorie'),
|
||||
'model_lie' => trans('type d\'élement lié'),
|
||||
'id_lie' => trans('élement lié')
|
||||
'user_id' => \trans('utilisateur'),
|
||||
'activity' => \trans('type d\'activitée'),
|
||||
'model_lie' => \trans('type d\'élément lié'),
|
||||
'id_lie' => \trans('élément lié'),
|
||||
'slot' => \trans('ligne de la journée'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,22 +9,22 @@ class UpdateMessage extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
/** @var \App\Models\User|null $user */
|
||||
$user = auth()->user();
|
||||
|
||||
|
||||
return auth()->check() && $user->isAdmin();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
|
|
|
|||
|
|
@ -10,12 +10,13 @@ class UserLabeledResource extends ResourceCollection
|
|||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param mixed $request
|
||||
* @return array
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
public function toArray($request)
|
||||
{
|
||||
// phpcs:enable
|
||||
return $this->collection->mapWithKeys(function (User $user, $key) {
|
||||
return [
|
||||
$key => [
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class AutoCloseOldTickets
|
|||
})->get();
|
||||
/** @var \App\Models\Ticket $ticket */
|
||||
foreach ($tickets as $ticket) {
|
||||
/** @var \App\Enums\TicketStatus */
|
||||
$oldStatus = $ticket->status;
|
||||
$ticket->status = TicketStatus::archived();
|
||||
$ticket->saveQuietly();
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ class SendTicketMentionMail implements ShouldQueue
|
|||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Mail\TicketMention $mail
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user, TicketMention $mail)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class SendUserCreatedEmail implements ShouldQueue
|
|||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user)
|
||||
|
|
|
|||
64
app/Lib/CollectionHelper.php
Normal file
64
app/Lib/CollectionHelper.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace App\Lib;
|
||||
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class CollectionHelper
|
||||
{
|
||||
/**
|
||||
* Paginate a collection
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $results
|
||||
* @param integer $pageSize
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public static function paginate(Collection $results, int $pageSize): LengthAwarePaginator
|
||||
{
|
||||
$page = Paginator::resolveCurrentPage('page');
|
||||
|
||||
return self::paginateManually($results, $pageSize, $page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate a collection
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $results
|
||||
* @param integer $pageSize
|
||||
* @param integer $page
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public static function paginateManually(Collection $results, int $pageSize, int $page = 1): LengthAwarePaginator
|
||||
{
|
||||
$total = $results->count();
|
||||
|
||||
return self::paginator($results->forPage($page, $pageSize), $total, $pageSize, $page, [
|
||||
'path' => Paginator::resolveCurrentPath(),
|
||||
'pageName' => 'page',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new length-aware paginator instance.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $items
|
||||
* @param integer $total
|
||||
* @param integer $perPage
|
||||
* @param integer $currentPage
|
||||
* @param array $options
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
protected static function paginator(Collection $items, int $total, int $perPage, int $currentPage, array $options)
|
||||
{
|
||||
return Container::getInstance()->makeWith(LengthAwarePaginator::class, [
|
||||
'items' => $items,
|
||||
'total' => $total,
|
||||
'perPage' => $perPage,
|
||||
'currentPage' => $currentPage,
|
||||
'options' => $options
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ class AddStatusMessages
|
|||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param TicketStatusChanged $event
|
||||
* @param \App\Events\TicketStatusChanged $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(TicketStatusChanged $event)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class HandleLoggable
|
|||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param Loggable $loggable
|
||||
* @param \App\Events\Loggable $loggable
|
||||
* @return void
|
||||
*/
|
||||
public function handle(Loggable $loggable)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class SendNotificationMailToAdmin
|
|||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param NotifyTicketCreator $event
|
||||
* @param \App\Events\NotifyAdmin $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(NotifyAdmin $event)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class SendNotificationMailToTicketCreator
|
|||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param NotifyTicketCreator $event
|
||||
* @param \App\Events\NotifyTicketCreator $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(NotifyTicketCreator $event)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class SendSubscriptionsNotificationsMail
|
|||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param NotifySubscriptions $event
|
||||
* @param \App\Events\NotifySubscriptions $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(NotifySubscriptions $event)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Ticket;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
|
@ -11,14 +12,16 @@ class NewTicket extends Mailable
|
|||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var \App\Models\Ticket */
|
||||
private $ticket;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($ticket)
|
||||
public function __construct(Ticket $ticket)
|
||||
{
|
||||
$this->ticket = $ticket;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class TicketMention extends Mailable
|
|||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var Ticket */
|
||||
/** @var \App\Models\Ticket */
|
||||
private $ticket;
|
||||
|
||||
/** @var string */
|
||||
|
|
@ -22,6 +22,8 @@ class TicketMention extends Mailable
|
|||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @param string $corpsMaj
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Ticket $ticket, string $corpsMaj)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class TicketUpdate extends Mailable
|
|||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var Ticket */
|
||||
/** @var \App\Models\Ticket */
|
||||
private $ticket;
|
||||
|
||||
/** @var string */
|
||||
|
|
@ -22,6 +22,8 @@ class TicketUpdate extends Mailable
|
|||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @param string $corpsMaj
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Ticket $ticket, string $corpsMaj)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,13 @@ use Illuminate\Mail\Mailable;
|
|||
|
||||
class UserCreatedMail extends Mailable
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user)
|
||||
|
|
|
|||
61
app/Models/Company.php
Normal file
61
app/Models/Company.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudAction;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudType;
|
||||
use Kwaadpepper\CrudPolicies\Traits\IsCrudModel;
|
||||
|
||||
class Company extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use IsCrudModel;
|
||||
|
||||
/**
|
||||
* Crud label column
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $crudLabelColumn = 'name';
|
||||
|
||||
/**
|
||||
* Crud value column
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name'
|
||||
];
|
||||
|
||||
/**
|
||||
* Company
|
||||
*
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'name' => [
|
||||
'label' => trans('Nom'),
|
||||
'type' => CrudType::string(),
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::update(),
|
||||
CrudAction::create()
|
||||
]
|
||||
],
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,18 +18,43 @@ class File extends Model
|
|||
use HasFactory;
|
||||
use IsCrudModel;
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to Enums.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $enumCasts = [
|
||||
'category' => FileCategory::class,
|
||||
'type' => FileType::class
|
||||
];
|
||||
|
||||
/**
|
||||
* Crud label column
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $crudLabelColumn = 'name';
|
||||
|
||||
/**
|
||||
* Crud value column
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['type', 'uri', 'file', 'name', 'category'];
|
||||
|
||||
public function __construct($attributes = [])
|
||||
/**
|
||||
* File
|
||||
*
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'name' => [
|
||||
|
|
@ -119,6 +144,11 @@ class File extends Model
|
|||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
static::created(function (File $file) {
|
||||
|
|
@ -126,16 +156,33 @@ class File extends Model
|
|||
});
|
||||
}
|
||||
|
||||
// * RELATIONSHIPS
|
||||
|
||||
/**
|
||||
* MorphTo parent object relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
public function parent()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
/**
|
||||
* MorphTo parent object site relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
public function parentSite()
|
||||
{
|
||||
return $this->morphTo('parent', 'site');
|
||||
}
|
||||
|
||||
/**
|
||||
* MorphTo parent object project relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
public function parentProject()
|
||||
{
|
||||
return $this->morphTo('parent', 'project');
|
||||
|
|
|
|||
390
app/Models/Invoice.php
Normal file
390
app/Models/Invoice.php
Normal file
|
|
@ -0,0 +1,390 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\Invoice\TaskType;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudAction;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudType;
|
||||
use Kwaadpepper\CrudPolicies\Traits\IsCrudModel;
|
||||
use Meneses\LaravelMpdf\LaravelMpdf;
|
||||
|
||||
class Invoice extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use IsCrudModel;
|
||||
|
||||
/**
|
||||
* Crud label column
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $crudLabelColumn = 'ref';
|
||||
|
||||
/**
|
||||
* Crud value column
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'ref', 'firstname', 'lastname',
|
||||
'object', 'tasks', 'total', 'total_days',
|
||||
'comment', 'show_days', 'signed_date',
|
||||
'sent_client_date', 'sent_accounting_date',
|
||||
'site_id', 'company_id', 'invoiced_to_id'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'tasks' => 'array',
|
||||
'signed_date' => 'date',
|
||||
'sent_client_date' => 'date',
|
||||
'sent_accounting_date' => 'date',
|
||||
];
|
||||
|
||||
/**
|
||||
* Invoice
|
||||
*
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'ref' => [
|
||||
'label' => trans('Réference'),
|
||||
'type' => CrudType::string(),
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view()
|
||||
]
|
||||
],
|
||||
'firstname' => [
|
||||
'label' => trans('Prénom'),
|
||||
'type' => CrudType::string(),
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'lastname' => [
|
||||
'label' => trans('Nom'),
|
||||
'type' => CrudType::string(),
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'object' => [
|
||||
'label' => trans('Object'),
|
||||
'type' => CrudType::string(),
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
// * Truncated on view any
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'tasks' => [
|
||||
'label' => trans('Tâches'),
|
||||
'type' => CrudType::json(),
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'total' => [
|
||||
'label' => trans('Montant total'),
|
||||
'type' => CrudType::float(),
|
||||
'nullable' => false,
|
||||
'readonly' => true,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
]
|
||||
],
|
||||
'total_days' => [
|
||||
'label' => trans('Montant total jours'),
|
||||
'type' => CrudType::float(),
|
||||
'nullable' => false,
|
||||
'readonly' => true,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
]
|
||||
],
|
||||
'comment' => [
|
||||
'label' => trans('Commentaire'),
|
||||
'type' => CrudType::text(),
|
||||
'nullable' => true,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'show_days' => [
|
||||
'label' => trans('Afficher les jours'),
|
||||
'type' => CrudType::boolean(),
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'signed_date' => [
|
||||
'label' => trans('Date de signature'),
|
||||
'type' => CrudType::datetime(),
|
||||
'nullable' => true,
|
||||
'readonly' => true,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
]
|
||||
],
|
||||
'sent_client_date' => [
|
||||
'label' => trans('Date d\'envoi client'),
|
||||
'type' => CrudType::datetime(),
|
||||
'nullable' => true,
|
||||
'readonly' => true,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
]
|
||||
],
|
||||
'sent_accounting_date' => [
|
||||
'label' => trans('Date d\'envoi compta'),
|
||||
'type' => CrudType::datetime(),
|
||||
'nullable' => true,
|
||||
'readonly' => true,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
]
|
||||
],
|
||||
'site_id' => [
|
||||
'label' => trans('models.classes.sites'),
|
||||
'type' => CrudType::belongsTo(),
|
||||
'belongsTo' => Site::class,
|
||||
'belongsToLabel' => 'site',
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'company_id' => [
|
||||
'label' => trans('models.classes.companies'),
|
||||
'type' => CrudType::belongsTo(),
|
||||
'belongsTo' => Company::class,
|
||||
'belongsToLabel' => 'companie',
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'invoiced_to_id' => [
|
||||
'label' => trans('Entité à facturer'),
|
||||
'type' => CrudType::belongsTo(),
|
||||
'belongsTo' => Company::class,
|
||||
'belongsToLabel' => 'entité',
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
CrudAction::create(),
|
||||
CrudAction::update()
|
||||
]
|
||||
],
|
||||
'created_at' => [
|
||||
'label' => trans('Crée le'),
|
||||
'type' => CrudType::datetime(),
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::view(),
|
||||
]
|
||||
],
|
||||
'updated_at' => [
|
||||
'label' => trans('Mis à jour'),
|
||||
'type' => CrudType::datetime(),
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
]
|
||||
],
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
$model->ref = \sprintf(
|
||||
'%s_%s_%s',
|
||||
Carbon::now()->isoFormat('YYYY'),
|
||||
Str::padLeft((Invoice::whereYear('created_at', Carbon::now()->isoFormat('YYYY'))
|
||||
->whereMonth('created_at', Carbon::now()->isoFormat('MM'))
|
||||
->count() + 1) ?: 1, 4, '0'),
|
||||
Str::substr(Str::upper(Str::slug(User::query()->inRandomOrder()->first()->name)), 0, 1)
|
||||
);
|
||||
$model->total_days = collect($model->tasks)
|
||||
/** @var null|float $previous */
|
||||
->reduce(function ($previous, array $task) {
|
||||
return \floatval($task['days']) + \floatval($previous);
|
||||
});
|
||||
$model->total = collect($model->tasks)
|
||||
/** @var null|float $previous */
|
||||
->reduce(function ($previous, array $task) {
|
||||
return \floatval($task['amount']) + \floatval($previous);
|
||||
});
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
$model->total_days = collect($model->tasks)
|
||||
/** @var null|float $previous */
|
||||
->reduce(function ($previous, array $task) {
|
||||
return \floatval($task['days']) + \floatval($previous);
|
||||
});
|
||||
$model->total = collect($model->tasks)
|
||||
/** @var null|float $previous */
|
||||
->reduce(function ($previous, array $task) {
|
||||
return \floatval($task['amount']) + \floatval($previous);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// * RELATIONSHIPS
|
||||
|
||||
/**
|
||||
* BelongsTo Site
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function site()
|
||||
{
|
||||
return $this->BelongsTo(Site::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* BelongsTo Company
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function company()
|
||||
{
|
||||
return $this->BelongsTo(Company::class);
|
||||
}
|
||||
/**
|
||||
* BelongsTo Company
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function companyInvoiced()
|
||||
{
|
||||
return $this->BelongsTo(Company::class, 'invoiced_to_id');
|
||||
}
|
||||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Get the tasks line structure skel
|
||||
*
|
||||
* @return array<string,string|float>
|
||||
*/
|
||||
public static function getTaskStructure(): array
|
||||
{
|
||||
return [
|
||||
// * string
|
||||
'desc' => '',
|
||||
// * usigned float
|
||||
'days' => 0,
|
||||
// * Invoice\TaskType value
|
||||
'type' => TaskType::web()->value,
|
||||
// * usigned float
|
||||
'amount' => 0,
|
||||
// * package ID if task type package or null
|
||||
'package' => null
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Invoice
|
||||
*
|
||||
* @return LaravelMpdf
|
||||
*/
|
||||
public function generateInvoice(): LaravelMpdf
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Package> */
|
||||
$packages = Package::get()->keyBy('id')->all();
|
||||
|
||||
/** @var \Meneses\LaravelMpdf\LaravelMpdfWrapper */
|
||||
$mpdf = app('mpdf.wrapper');
|
||||
/** @var \Meneses\LaravelMpdf\LaravelMpdf */
|
||||
$pdf = $mpdf->loadView(
|
||||
'documents.invoice',
|
||||
$this->toArray(),
|
||||
[
|
||||
'site' => $this->site,
|
||||
'company' => $this->company,
|
||||
'companyInvoiced' => $this->companyInvoiced,
|
||||
'packages' => $packages,
|
||||
],
|
||||
[
|
||||
'mode' => '',
|
||||
'format' => 'A4',
|
||||
'default_font_size' => '12',
|
||||
'default_font' => 'sans-serif',
|
||||
'margin_left' => 0,
|
||||
'margin_right' => 0,
|
||||
'margin_top' => 0,
|
||||
'margin_bottom' => 0,
|
||||
'margin_header' => 0,
|
||||
'margin_footer' => 0,
|
||||
'orientation' => 'P',
|
||||
'title' => __('Devis Équipe Web :ref', ['ref' => $this->ref]),
|
||||
'author' => 'Equipe Web',
|
||||
'watermark' => '',
|
||||
'show_watermark' => false,
|
||||
'watermark_font' => 'sans-serif',
|
||||
'display_mode' => 'fullpage',
|
||||
'watermark_text_alpha' => 0.1,
|
||||
'custom_font_dir' => '',
|
||||
'custom_font_data' => [],
|
||||
'auto_language_detection' => false,
|
||||
'temp_dir' => ini_get('upload_tmp_dir') ? ini_get('upload_tmp_dir') : sys_get_temp_dir(),
|
||||
'pdfa' => false,
|
||||
'pdfaauto' => false,
|
||||
]
|
||||
);
|
||||
return $pdf;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,13 +13,33 @@ class Log extends Model
|
|||
use HasFactory;
|
||||
use IsCrudModel;
|
||||
|
||||
/**
|
||||
* Crud label column
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $crudLabelColumn = 'id';
|
||||
|
||||
/**
|
||||
* Crud value column
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['entry'];
|
||||
|
||||
public function __construct($attributes = [])
|
||||
/**
|
||||
* Log
|
||||
*
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'id' => [
|
||||
|
|
@ -54,6 +74,11 @@ class Log extends Model
|
|||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function (Log $log) {
|
||||
|
|
@ -61,21 +86,43 @@ class Log extends Model
|
|||
});
|
||||
}
|
||||
|
||||
// * RELATIONSHIPS
|
||||
|
||||
/**
|
||||
* BelongsTo User relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* MorphTo parent object relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
public function parent()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
/**
|
||||
* MorphTo parent object site relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
public function parentSite()
|
||||
{
|
||||
return $this->morphTo('parent', 'site');
|
||||
}
|
||||
|
||||
/**
|
||||
* MorphTo parent object project relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
public function parentProject()
|
||||
{
|
||||
return $this->morphTo('parent', 'project');
|
||||
|
|
|
|||
79
app/Models/Package.php
Normal file
79
app/Models/Package.php
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudAction;
|
||||
use Kwaadpepper\CrudPolicies\Enums\CrudType;
|
||||
use Kwaadpepper\CrudPolicies\Traits\IsCrudModel;
|
||||
|
||||
class Package extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use IsCrudModel;
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* Crud label column
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $crudLabelColumn = 'name';
|
||||
|
||||
/**
|
||||
* Crud value column
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $crudValueColumn = 'id';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name', 'amount'
|
||||
];
|
||||
|
||||
/**
|
||||
* Package
|
||||
*
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
self::$editableProperties = [
|
||||
'name' => [
|
||||
'label' => trans('Nom'),
|
||||
'type' => CrudType::string(),
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::update(),
|
||||
CrudAction::create()
|
||||
]
|
||||
],
|
||||
'amount' => [
|
||||
'label' => trans('Montant (par jour)'),
|
||||
'type' => CrudType::float(),
|
||||
'nullable' => false,
|
||||
'actions' => [
|
||||
CrudAction::viewAny(),
|
||||
CrudAction::view(),
|
||||
CrudAction::update(),
|
||||
CrudAction::create()
|
||||
]
|
||||
],
|
||||
];
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,6 +14,11 @@ class Schedule extends Model
|
|||
use HasFactory;
|
||||
use CastsEnums;
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to Enums.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $enumCasts = [
|
||||
'activity' => ActivityType::class,
|
||||
'model_lie' => CellModel::class
|
||||
|
|
@ -28,6 +33,11 @@ class Schedule extends Model
|
|||
'date' => 'date',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'date',
|
||||
|
|
@ -38,28 +48,34 @@ class Schedule extends Model
|
|||
'model_lie'
|
||||
];
|
||||
|
||||
// * RELATIONSHIPS
|
||||
|
||||
/**
|
||||
* BelongsTo User relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
// relationship to linked objet
|
||||
/**
|
||||
* relationship to linked objet
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function relatedModel()
|
||||
{
|
||||
switch ($this->model_lie) {
|
||||
case 'sites':
|
||||
return $this->belongsTo(Site::class, 'id_lie');
|
||||
break;
|
||||
case 'projects':
|
||||
return $this->belongsTo(Project::class, 'id_lie');
|
||||
break;
|
||||
case 'tickets':
|
||||
return $this->belongsTo(Ticket::class, 'id_lie');
|
||||
break;
|
||||
default:
|
||||
// no model
|
||||
return new BelongsTo($this->newQuery(), $this, '', '', '');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,5 +6,10 @@ use Illuminate\Database\Eloquent\Relations\Pivot;
|
|||
|
||||
class SiteUser extends Pivot
|
||||
{
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $timestamps = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@ class AccountPolicy extends RootPolicy
|
|||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param User $user
|
||||
* @param Model $model
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
// phpcs:enable
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@ class BrandPolicy extends RootPolicy
|
|||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param User $user
|
||||
* @param Model $model
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
// phpcs:enable
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
|
|
|
|||
38
app/Policies/CompanyPolicy.php
Normal file
38
app/Policies/CompanyPolicy.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserRoleRules as URR;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Kwaadpepper\CrudPolicies\Policies\RootPolicy;
|
||||
|
||||
class CompanyPolicy extends RootPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
// phpcs:enable
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
$this->policies = [
|
||||
'company' => [
|
||||
'viewAny' => URR::make('userIsAdmin', $user),
|
||||
'create' => URR::make('userIsAdmin', $user),
|
||||
'update' => URR::make('userIsAdmin', $user),
|
||||
'delete' => URR::make('userIsAdmin', $user)
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -15,10 +15,9 @@ class CreditLogPolicy extends RootPolicy
|
|||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param User $user
|
||||
* @param Model $model
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@ class EstimationPolicy extends RootPolicy
|
|||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param User $user
|
||||
* @param Model $model
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
// phpcs:enable
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@ class FilePolicy extends RootPolicy
|
|||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param User $user
|
||||
* @param Model $model
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
// phpcs:enable
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
|
|
|
|||
47
app/Policies/InvoicePolicy.php
Normal file
47
app/Policies/InvoicePolicy.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserRoleRules as URR;
|
||||
use App\Policies\Rules\InvoiceStaticRules as ISR;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Kwaadpepper\CrudPolicies\Policies\RootPolicy;
|
||||
|
||||
class InvoicePolicy extends RootPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
// phpcs:enable
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
$this->policies = [
|
||||
'invoice' => [
|
||||
'viewAny' => URR::make('userIsAdmin', $user),
|
||||
'view' => URR::make('userIsAdmin', $user),
|
||||
'create' => URR::make('userIsAdmin', $user),
|
||||
'update' => [
|
||||
URR::make('userIsAdmin', $user),
|
||||
ISR::make('invoiceHasNotBeenSentTotheClient', $user),
|
||||
],
|
||||
'delete' => URR::make('denyEveryOne'),
|
||||
'download' => [
|
||||
URR::make('userIsAdmin', $user),
|
||||
ISR::make('invoiceHasTasks', $user),
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -15,13 +15,14 @@ class LabelPolicy extends RootPolicy
|
|||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param User $user
|
||||
* @param Model $model
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
// phpcs:enable
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -17,10 +17,9 @@ class LogPolicy extends RootPolicy
|
|||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param User $user
|
||||
* @param Model $model
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@ class MarkerPolicy extends RootPolicy
|
|||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param User $user
|
||||
* @param Model $model
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed, Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
// phpcs:enable
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
|
|
|
|||
38
app/Policies/PackagePolicy.php
Normal file
38
app/Policies/PackagePolicy.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserRoleRules as URR;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Kwaadpepper\CrudPolicies\Policies\RootPolicy;
|
||||
|
||||
class PackagePolicy extends RootPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
// phpcs:enable
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
$this->policies = [
|
||||
'package' => [
|
||||
'viewAny' => URR::make('userIsAdmin', $user),
|
||||
'create' => URR::make('userIsAdmin', $user),
|
||||
'update' => URR::make('userIsAdmin', $user),
|
||||
'delete' => URR::make('userIsAdmin', $user)
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -15,13 +15,14 @@ class ProjectPolicy extends RootPolicy
|
|||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param User $user
|
||||
* @param Model $model
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed, Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
// phpcs:enable
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ abstract class EstimationStaticRules extends StaticRules
|
|||
/**
|
||||
* Estimation is pending
|
||||
*
|
||||
* @param Estimation $model
|
||||
* @param \App\Models\Credit\Estimation $model
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function estimateIsPending(Estimation $model): bool
|
||||
|
|
|
|||
35
app/Policies/Rules/InvoiceStaticRules.php
Normal file
35
app/Policies/Rules/InvoiceStaticRules.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies\Rules;
|
||||
|
||||
use App\Models\Invoice;
|
||||
use Kwaadpepper\CrudPolicies\Policies\Rules\StaticRules;
|
||||
|
||||
/**
|
||||
* Invoice Policiy Static Rules
|
||||
* ! Rules has to return boolean value
|
||||
*/
|
||||
abstract class InvoiceStaticRules extends StaticRules
|
||||
{
|
||||
/**
|
||||
* Invoice has not been sent ot the client
|
||||
*
|
||||
* @param \App\Models\Invoice $model
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function invoiceHasNotBeenSentTotheClient(Invoice $model): bool
|
||||
{
|
||||
return \is_null($model->sent_client_date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoice has some tasks
|
||||
*
|
||||
* @param \App\Models\Invoice $model
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function invoiceHasTasks(Invoice $model): bool
|
||||
{
|
||||
return (bool)\count($model->tasks);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,8 +15,8 @@ abstract class LogStaticRules extends StaticRules
|
|||
/**
|
||||
* Log Is owned by user.
|
||||
*
|
||||
* @param User $user
|
||||
* @param Log $log
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\Log $log
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function logIsOwnedByUser(User $user, Log $log): bool
|
||||
|
|
|
|||
|
|
@ -12,6 +12,13 @@ use Kwaadpepper\CrudPolicies\Policies\Rules\StaticRules;
|
|||
*/
|
||||
abstract class SiteStaticRules extends StaticRules
|
||||
{
|
||||
/**
|
||||
* Check if a user can access a ticket
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function userSitesHasTicket(User $user, Ticket $ticket)
|
||||
{
|
||||
return $user->sites->contains($ticket->site_id);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ abstract class TicketStaticRules extends StaticRules
|
|||
/**
|
||||
* Ticket is not in production
|
||||
*
|
||||
* @param Ticket $ticket
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function ticketIsNotInProduction(Ticket $ticket): bool
|
||||
|
|
@ -26,7 +26,7 @@ abstract class TicketStaticRules extends StaticRules
|
|||
/**
|
||||
* Ticket is not archived
|
||||
*
|
||||
* @param Ticket $ticket
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function ticketIsNotArchived(Ticket $ticket): bool
|
||||
|
|
@ -37,7 +37,7 @@ abstract class TicketStaticRules extends StaticRules
|
|||
/**
|
||||
* Ticket has brand which has at least one account
|
||||
*
|
||||
* @param Ticket $ticket
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function ticketsBrandHasAnAccount(Ticket $ticket): bool
|
||||
|
|
@ -52,7 +52,7 @@ abstract class TicketStaticRules extends StaticRules
|
|||
/**
|
||||
* Ticket does already have an estimation
|
||||
*
|
||||
* @param Ticket $ticket
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function ticketDoesHaveEstimation(Ticket $ticket): bool
|
||||
|
|
@ -63,7 +63,7 @@ abstract class TicketStaticRules extends StaticRules
|
|||
/**
|
||||
* Ticket does not already have an estimation
|
||||
*
|
||||
* @param Ticket $ticket
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function ticketDoesntHaveEstimation(Ticket $ticket): bool
|
||||
|
|
@ -74,7 +74,7 @@ abstract class TicketStaticRules extends StaticRules
|
|||
/**
|
||||
* Ticket is not internal
|
||||
*
|
||||
* @param Ticket $ticket
|
||||
* @param \App\Models\Ticket $ticket
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function ticketIsNotInternal(Ticket $ticket): bool
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@ class SitePolicy extends RootPolicy
|
|||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param User $user
|
||||
* @param Model $model
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
// phpcs:enable
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ class TicketPolicy extends RootPolicy
|
|||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param User $user
|
||||
* @param Model $model
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
*/
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@ class UserPolicy extends RootPolicy
|
|||
/**
|
||||
* Init policies on call
|
||||
*
|
||||
* @param User $user
|
||||
* @param Model $model
|
||||
* @param \App\Models\User $user
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
*/
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
|
||||
public function setPolicies(User $user, Model $model = null)
|
||||
{
|
||||
// phpcs:enable
|
||||
/**
|
||||
* This first rule to return true in a policy action authorises the action
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace App\Providers;
|
|||
|
||||
use App\Models\MacroSchedule\Marker;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
|
@ -12,15 +13,6 @@ use Illuminate\Support\ServiceProvider;
|
|||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
|
|
@ -32,11 +24,31 @@ class AppServiceProvider extends ServiceProvider
|
|||
|
||||
URL::forceScheme('https');
|
||||
|
||||
if (config('app.env') === 'local') {
|
||||
setlocale(LC_TIME, strtoupper(config('app.locale')) . "_" . config('app.locale') . '.utf8');
|
||||
}
|
||||
// * LOCAL FORCE eg: for Carbon
|
||||
// * Remove numeric to prevent float seperator to breaking numeric transactions
|
||||
\collect([\LC_TIME, \LC_MESSAGES, \LC_COLLATE, \LC_CTYPE, \LC_MONETARY])
|
||||
->map(function ($contant) {
|
||||
setlocale(
|
||||
$contant,
|
||||
\sprintf(
|
||||
'%s_%s.UTF-8',
|
||||
config('app.locale'),
|
||||
\strtoupper(config('app.locale'))
|
||||
)
|
||||
);
|
||||
});
|
||||
Carbon::setLocale(config('app.locale'));
|
||||
|
||||
// * Force bootstrap paginator
|
||||
Paginator::useBootstrap();
|
||||
|
||||
// * HA PROXY FIX
|
||||
app()->singleton('clientIp', function () {
|
||||
if (config('app.env') === 'local') {
|
||||
return request()->getClientIp();
|
||||
}
|
||||
return request()->server('HTTP_X_FORWARDED_FOR') ?? request()->getClientIp();
|
||||
});
|
||||
|
||||
if (!app()->runningInConsole()) {
|
||||
$appInfos = Cache::remember('composer', 360, function () {
|
||||
|
|
|
|||
|
|
@ -3,12 +3,15 @@
|
|||
namespace App\Providers;
|
||||
|
||||
use App\Models\Brand;
|
||||
use App\Models\Company;
|
||||
use App\Models\Credit\Account;
|
||||
use App\Models\Credit\CreditLog;
|
||||
use App\Models\File;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Label;
|
||||
use App\Models\Log;
|
||||
use App\Models\MacroSchedule\Marker;
|
||||
use App\Models\Package;
|
||||
use App\Models\Project;
|
||||
use App\Models\Site;
|
||||
use App\Models\Ticket;
|
||||
|
|
@ -87,6 +90,9 @@ class RouteServiceProvider extends ServiceProvider
|
|||
Route::model('brand', Brand::class);
|
||||
Route::model('label', Label::class);
|
||||
Route::model('marker', Marker::class);
|
||||
Route::model('package', Package::class);
|
||||
Route::model('company', Company::class);
|
||||
Route::model('invoice', Invoice::class);
|
||||
Route::model('file', File::class);
|
||||
Route::model('log', Log::class);
|
||||
Route::model('user', User::class);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
|
@ -15,10 +16,8 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot()
|
||||
{
|
||||
$translations = collect();
|
||||
|
||||
foreach ($this->collectLocalesStrings() as $locale) {
|
||||
// suported locales
|
||||
// * Suported locales
|
||||
Cache::rememberForever(sprintf('translations.%s', $locale), function () use ($locale) {
|
||||
$translations = [
|
||||
'php' => $this->phpTranslations($locale),
|
||||
|
|
@ -29,7 +28,12 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
}
|
||||
}
|
||||
|
||||
private function collectLocalesStrings()
|
||||
/**
|
||||
* Gather provided langs checking from files
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
private function collectLocalesStrings(): Collection
|
||||
{
|
||||
return collect(File::allFiles(resource_path('lang/')))->flatMap(function ($file) {
|
||||
if ($file->getRelativePath()) {
|
||||
|
|
@ -38,23 +42,34 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
})->keys();
|
||||
}
|
||||
|
||||
private function phpTranslations($locale)
|
||||
/**
|
||||
* Gather all php translations
|
||||
*
|
||||
* @param string $locale
|
||||
* @return array
|
||||
*/
|
||||
private function phpTranslations(string $locale): array
|
||||
{
|
||||
$path = resource_path("lang/$locale");
|
||||
|
||||
return collect(File::allFiles($path))->flatMap(function ($file) use ($locale) {
|
||||
$key = ($translation = $file->getBasename('.php'));
|
||||
|
||||
return [$key => trans($translation, [], $locale)];
|
||||
});
|
||||
$translation = $file->getBasename('.php');
|
||||
return [$translation => trans($translation, [], $locale)];
|
||||
})->all();
|
||||
}
|
||||
|
||||
private function jsonTranslations($locale)
|
||||
/**
|
||||
* Gather json translations
|
||||
*
|
||||
* @param string $locale
|
||||
* @return array
|
||||
*/
|
||||
private function jsonTranslations(string $locale): array
|
||||
{
|
||||
$path = resource_path("lang/$locale.json");
|
||||
|
||||
if (is_string($path) && is_readable($path)) {
|
||||
return json_decode(file_get_contents($path), true);
|
||||
return json_decode(file_get_contents($path), true) ?? [];
|
||||
}
|
||||
|
||||
return [];
|
||||
|
|
|
|||
|
|
@ -10,12 +10,13 @@
|
|||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"carlos-meneses/laravel-mpdf": "^2.1",
|
||||
"doctrine/dbal": "^3.1",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"fideloper/proxy": "^4.4",
|
||||
"fruitcake/laravel-cors": "^2.0",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"kwaadpepper/crud-policies": "^0.4.5",
|
||||
"kwaadpepper/crud-policies": "^0.4.7",
|
||||
"kwaadpepper/enum": "^2.1",
|
||||
"kwaadpepper/exception-handler": "^0.0.9",
|
||||
"laravel-lang/lang": "~8.0",
|
||||
|
|
@ -23,6 +24,7 @@
|
|||
"laravel/framework": "^8.12",
|
||||
"laravel/tinker": "^2.5",
|
||||
"laravel/ui": "^3.3",
|
||||
"ldc/web-status-checker-laravel": "^1.0",
|
||||
"mews/purifier": "^3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
|
|
@ -72,5 +74,11 @@
|
|||
"post-create-project-cmd": [
|
||||
"@php artisan key:generate --ansi"
|
||||
]
|
||||
}
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "composer",
|
||||
"url": "https://gitlab.com/api/v4/group/16669037/-/packages/composer/packages.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
1026
composer.lock
generated
1026
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -15,7 +15,7 @@ return [
|
|||
|
||||
'default' => env('MAIL_MAILER', 'smtp'),
|
||||
|
||||
// Mail admin
|
||||
// * Mail admin
|
||||
'MAIL_ADMIN' => env('MAIL_ADMIN'),
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ return [
|
|||
* of your proxy (e.g. if using ELB or similar).
|
||||
*
|
||||
*/
|
||||
|
||||
'proxies' => '*',
|
||||
|
||||
/*
|
||||
|
|
@ -42,6 +43,10 @@ return [
|
|||
*
|
||||
* @link https://symfony.com/doc/current/deployment/proxies.html
|
||||
*/
|
||||
'headers' => Illuminate\Http\Request::HEADER_X_FORWARDED_ALL,
|
||||
|
||||
'headers' => Illuminate\Http\Request::HEADER_X_FORWARDED_FOR |
|
||||
Illuminate\Http\Request::HEADER_X_FORWARDED_HOST |
|
||||
Illuminate\Http\Request::HEADER_X_FORWARDED_PORT |
|
||||
Illuminate\Http\Request::HEADER_X_FORWARDED_PROTO,
|
||||
|
||||
];
|
||||
|
|
|
|||
28
database/factories/CompanyFactory.php
Normal file
28
database/factories/CompanyFactory.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Company;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class CompanyFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = Company::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->name,
|
||||
];
|
||||
}
|
||||
}
|
||||
83
database/factories/InvoiceFactory.php
Normal file
83
database/factories/InvoiceFactory.php
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Enums\Invoice\TaskType;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Package;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class InvoiceFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = Invoice::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
\mt_srand();
|
||||
$lines = \mt_rand(2, 9);
|
||||
$tasks = [];
|
||||
$total = 0;
|
||||
$totalDays = 0;
|
||||
for ($i = 0; $i < $lines; $i++) {
|
||||
$days = 0.125 * $this->faker->numberBetween(1, 4);
|
||||
$type = \collect(TaskType::toArray())->random();
|
||||
$amount = 0;
|
||||
switch ($type) {
|
||||
case TaskType::web():
|
||||
$amount = $days * $type->price;
|
||||
break;
|
||||
case TaskType::seo():
|
||||
$amount = $days * $type->price;
|
||||
break;
|
||||
case TaskType::package():
|
||||
$amount = $days * (\optional(Package::query()->inRandomOrder()->first())->amount ??
|
||||
$this->faker->randomFloat(null, 150, 650));
|
||||
break;
|
||||
case TaskType::package():
|
||||
$amount = $days * $this->faker->randomFloat(null, 150, 650);
|
||||
break;
|
||||
}
|
||||
$totalDays += $days;
|
||||
$total += $amount;
|
||||
/** @var \App\Enums\Invoice\TaskType */
|
||||
$taskType = \collect(TaskType::toArray())->random();
|
||||
$tasks[] = \array_merge(Invoice::getTaskStructure(), [
|
||||
'desc' => $this->faker->words(9, true),
|
||||
'days' => $days,
|
||||
'type' => $taskType->value,
|
||||
'amount' => $amount,
|
||||
'package' => 1
|
||||
]);
|
||||
} //end for
|
||||
|
||||
return [
|
||||
'firstname' => $this->faker->firstName,
|
||||
'lastname' => $this->faker->lastName,
|
||||
'object' => $this->faker->words(3, true),
|
||||
// * constructed object
|
||||
'tasks' => $tasks,
|
||||
// * constructed object result
|
||||
'total' => $total,
|
||||
// * constructed object result
|
||||
'total_days' => $totalDays,
|
||||
'comment' => $this->faker->text(\rand(20, 40)),
|
||||
'show_days' => $this->faker->boolean(75),
|
||||
'signed_date' => $this->faker->boolean(25) ?
|
||||
$this->faker->dateTimeBetween('-1 year', '+1 year') : null,
|
||||
'sent_client_date' => $this->faker->boolean(25) ?
|
||||
$this->faker->dateTimeBetween('-1 year', '+1 year') : null,
|
||||
'sent_accounting_date' => $this->faker->boolean(25) ?
|
||||
$this->faker->dateTimeBetween('-1 year', '+1 year') : null,
|
||||
];
|
||||
}
|
||||
}
|
||||
29
database/factories/PackageFactory.php
Normal file
29
database/factories/PackageFactory.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Package;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class PackageFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = Package::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->name,
|
||||
'amount' => $this->faker->unique()->randomFloat(2, 120, 850)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -26,8 +26,8 @@ class UserFactory extends Factory
|
|||
'name' => $this->faker->name,
|
||||
'email' => $this->faker->unique()->safeEmail,
|
||||
'email_verified_at' => now(),
|
||||
// * password
|
||||
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
|
||||
// password
|
||||
'remember_token' => Str::random(10),
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreatePackagesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('packages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->string('name');
|
||||
$table->unsignedFloat('amount')->comment('The cost per day');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('packages');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateCompaniesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('companies', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->string('name');
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('companies');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateInvoicesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('invoices', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('ref')
|
||||
->comment(sprintf(
|
||||
'%s. %s. %s. %s.',
|
||||
'The invoice reference built as YYYY_MM_INCREMENT_USER',
|
||||
'INCREMENT is the N invoice of the month',
|
||||
'USER is the first two letters of the user who last edited the invoice',
|
||||
'This field has to generated only on create'
|
||||
));
|
||||
|
||||
$table->string('firstname')->comment('The person to which the invoice is addressed.');
|
||||
$table->string('lastname')->comment('The person to which the invoice is addressed.');
|
||||
|
||||
$table->string('object')->comment('The invoice object.');
|
||||
|
||||
$table->text('tasks')
|
||||
->comment(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'A JSON object, each line has to be contructed using these fields description, days, type Invoice\TaskType, amount'
|
||||
);
|
||||
|
||||
$table->unsignedFloat('total')->comment('The total calculated using all tasks');
|
||||
$table->unsignedFloat('total_days')->comment('The total days calculated using all tasks');
|
||||
|
||||
$table->text('comment')->nullable()
|
||||
->comment('Any comment joined to the invoice');
|
||||
|
||||
$table->boolean('show_days')->comment('Show days on the printed invoice');
|
||||
|
||||
$table->timestamp('signed_date')->nullable()
|
||||
->comment('The date the invoice was signed');
|
||||
$table->timestamp('sent_client_date')->nullable()
|
||||
->comment('The date the invoice was send to the client');
|
||||
$table->timestamp('sent_accounting_date')->nullable()
|
||||
->comment('The date the invoice was send to the client');
|
||||
|
||||
$table->foreignIdFor(Site::class)->constrained();
|
||||
$table->foreignIdFor(Company::class)->constrained();
|
||||
$table->foreignId('invoiced_to_id')
|
||||
->constrained((new Company())->getTable());
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('invoices');
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,5 @@ class DatabaseSeeder extends Seeder
|
|||
*/
|
||||
public function run()
|
||||
{
|
||||
// \App\Models\User::factory(10)->create();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
54
database/seeders/InvoicingSeeder.php
Normal file
54
database/seeders/InvoicingSeeder.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Package;
|
||||
use App\Models\Site;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class InvoicingSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Seed the application's database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
/** Reset all invoices */
|
||||
DB::table((new Invoice())->getTable())->truncate();
|
||||
|
||||
/** Reset all packages (forfaits) */
|
||||
Package::all()->map(function (Package $model) {
|
||||
$model->deleteOrFail();
|
||||
});
|
||||
Package::factory(6)->create();
|
||||
|
||||
/** Reset all companies */
|
||||
Company::all()->map(function (Company $model) {
|
||||
$model->deleteOrFail();
|
||||
});
|
||||
Company::factory(6)->create();
|
||||
|
||||
Invoice::factory(45)->make()->each(function (Invoice $model) {
|
||||
$model->ref = \sprintf(
|
||||
'%s_%s_%s',
|
||||
Carbon::now()->isoFormat('YYYY-MM'),
|
||||
Str::padLeft((Invoice::whereYear('created_at', Carbon::now()->isoFormat('YYYY'))
|
||||
->whereMonth('created_at', Carbon::now()->isoFormat('MM'))
|
||||
->count() + 1) ?: 1, 4, '0'),
|
||||
Str::substr(Str::upper(Str::slug(User::query()->inRandomOrder()->first()->name)), 0, 1)
|
||||
);
|
||||
$model->site()->associate(Site::query()->inRandomOrder()->first());
|
||||
$model->company()->associate(Company::query()->inRandomOrder()->first());
|
||||
$model->companyInvoiced()->associate(Company::query()->inRandomOrder()->first());
|
||||
$model->saveQuietly();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
{
|
||||
"include": [
|
||||
"./resources/js/**/*"
|
||||
]
|
||||
}
|
||||
{
|
||||
"include": ["./resources/ts/**/*"]
|
||||
}
|
||||
|
|
|
|||
8820
package-lock.json
generated
8820
package-lock.json
generated
File diff suppressed because it is too large
Load diff
51
package.json
51
package.json
|
|
@ -8,36 +8,57 @@
|
|||
"watch-poll": "mix watch -- --watch-options-poll=1000",
|
||||
"hot": "mix watch --hot",
|
||||
"production": "npm run clear-manifest && mix --production",
|
||||
"prod": "npm run production"
|
||||
"prod": "npm run production",
|
||||
"eslint": "node ./node_modules/.bin/eslint -c .eslintrc.json ./resources",
|
||||
"eslint-ci": "node ./node_modules/.bin/eslint -c .eslintrc.json ./resources -f junit",
|
||||
"stylelint": "npx stylelint '**/*.scss'",
|
||||
"stylelint-ci": "npx stylelint '**/*.scss' -f json"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-transform-async-to-generator": "^7.16.8",
|
||||
"@fortawesome/fontawesome-free": "^6.1.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.1.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.1.2",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.1.2",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.1.2",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.1.2",
|
||||
"@fortawesome/vue-fontawesome": "^3.0.1",
|
||||
"@popperjs/core": "^2.11.5",
|
||||
"@vue/compiler-sfc": "^3.2.37",
|
||||
"autoprefixer": "10.4.5",
|
||||
"@types/bootstrap": "^5.1.12",
|
||||
"@types/toastify-js": "^1.11.1",
|
||||
"@types/vue-select": "^3.16.0",
|
||||
"@types/webpack-env": "^1.17.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.35.1",
|
||||
"@typescript-eslint/parser": "^5.35.1",
|
||||
"@vue/eslint-config-typescript": "^11.0.0",
|
||||
"axios": "^0.21.1",
|
||||
"bootstrap": "^5.1.3",
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
"cross-env": "^7.0",
|
||||
"css-loader": "^6.7.1",
|
||||
"del-cli": "^4.0.1",
|
||||
"eslint": "^8.22.0",
|
||||
"eslint-plugin-vue": "^9.4.0",
|
||||
"eslint-webpack-plugin": "^3.2.0",
|
||||
"glightbox": "^3.2.0",
|
||||
"laravel-mix": "^6.0.16",
|
||||
"laravel-mix": "^6.0.6",
|
||||
"laravel-mix-clean": "^0.1.0",
|
||||
"laravel-mix-eslint": "^0.2.0",
|
||||
"laravel-mix-polyfill": "^3.0.1",
|
||||
"laravel-mix-stylelint": "^1.0.0",
|
||||
"lodash": "^4.17.19",
|
||||
"moment": "^2.29.3",
|
||||
"resolve-url-loader": "^3.1.0",
|
||||
"sass": "^1.15.2",
|
||||
"sass-loader": "^8.0.2",
|
||||
"prettier": "^2.7.1",
|
||||
"resolve-url-loader": "^5.0.0",
|
||||
"sass": "^1.52.1",
|
||||
"sass-loader": "^12.6.0",
|
||||
"stylelint": "^14.11.0",
|
||||
"stylelint-config-idiomatic-order": "^8.1.0",
|
||||
"stylelint-config-sass-guidelines": "^9.0.1",
|
||||
"stylelint-webpack-plugin": "^3.3.0",
|
||||
"sweetalert2": "^11.4.16",
|
||||
"toastify-js": "^1.11.2",
|
||||
"vue": "^2.6.14",
|
||||
"vue-loader": "^15.9.7",
|
||||
"vue-select": "^3.13.0",
|
||||
"vue-style-loader": "^4.1.3",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
"ts-loader": "^9.3.0",
|
||||
"typescript": "^4.7.4",
|
||||
"vue": "^3.2.36",
|
||||
"vue-loader": "^16.8.3",
|
||||
"vue-select": "^4.0.0-beta.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ruleset name="LDC Laravel"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
|
||||
<ruleset name="LDC Laravel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
|
||||
<description>Created with the PHP Coding Standard Generator. http://edorian.github.com/php-coding-standard-generator/</description>
|
||||
<arg name="colors" />
|
||||
<arg name="extensions" value="php" />
|
||||
<file>app/</file>
|
||||
<file>config/</file>
|
||||
<file>database/factories</file>
|
||||
<file>database/seeders</file>
|
||||
<file>routes/</file>
|
||||
<file>tests/</file>
|
||||
<rule ref="PSR1" />
|
||||
<rule ref="PSR12" />
|
||||
|
||||
|
|
|
|||
BIN
resources/assets/documents/invoice/logo_ldc.jpg
Normal file
BIN
resources/assets/documents/invoice/logo_ldc.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
6
resources/js/app.js
vendored
6
resources/js/app.js
vendored
|
|
@ -1,6 +0,0 @@
|
|||
require('./bootstrap')
|
||||
require('./session_watch')
|
||||
require('./vue')
|
||||
require('./files_add')
|
||||
require('./label_colorize')
|
||||
require('./confirm')
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue