Merge pull request #3153 from CihanSenturk/add-export-validation-warning-message
Add export validation warning message
This commit is contained in:
commit
47fbe71669
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Abstracts;
|
||||
|
||||
use App\Abstracts\Http\FormRequest;
|
||||
use App\Events\Export\HeadingsPreparing;
|
||||
use App\Events\Export\RowsPreparing;
|
||||
use App\Notifications\Common\ExportFailed;
|
||||
|
|
@ -14,11 +15,16 @@ use Maatwebsite\Excel\Concerns\FromCollection;
|
|||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||
use Maatwebsite\Excel\Concerns\WithStrictNullComparison;
|
||||
use Maatwebsite\Excel\Events\AfterSheet;
|
||||
use Maatwebsite\Excel\Events\BeforeSheet;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date as ExcelDate;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
|
||||
abstract class Export implements FromCollection, HasLocalePreference, ShouldAutoSize, ShouldQueue, WithHeadings, WithMapping, WithTitle, WithStrictNullComparison
|
||||
abstract class Export implements FromCollection, HasLocalePreference, ShouldAutoSize, ShouldQueue, WithHeadings, WithMapping, WithTitle, WithStrictNullComparison, WithEvents
|
||||
{
|
||||
use Exportable;
|
||||
|
||||
|
|
@ -28,10 +34,21 @@ abstract class Export implements FromCollection, HasLocalePreference, ShouldAuto
|
|||
|
||||
public $user;
|
||||
|
||||
public $request_class = null;
|
||||
|
||||
public $column_count; //number of columns to be auto sized
|
||||
|
||||
public $column_validations; //selects should have column_name and options
|
||||
|
||||
public $row_count; //number of rows that will have the dropdown
|
||||
|
||||
public function __construct($ids = null)
|
||||
{
|
||||
$this->ids = $ids;
|
||||
$this->fields = $this->fields();
|
||||
$this->column_validations = $this->columnValidations();
|
||||
$this->column_count = config('excel.exports.column_count');
|
||||
$this->row_count = config('excel.exports.row_count');
|
||||
$this->user = user();
|
||||
}
|
||||
|
||||
|
|
@ -99,4 +116,171 @@ abstract class Export implements FromCollection, HasLocalePreference, ShouldAuto
|
|||
{
|
||||
$this->user->notify(new ExportFailed($exception->getMessage()));
|
||||
}
|
||||
|
||||
public function columnValidations(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function afterSheet($event)
|
||||
{
|
||||
$condition = class_exists($this->request_class)
|
||||
? ! ($request = new $this->request_class) instanceof FormRequest
|
||||
: true;
|
||||
|
||||
|
||||
if (empty($this->column_validations) && $condition) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$alphas = range('A', 'Z');
|
||||
|
||||
foreach ($this->fields as $key => $value) {
|
||||
$drop_column = $alphas[$key];
|
||||
|
||||
if ($this->setColumnValidations($drop_column, $event, $value)) {
|
||||
continue;
|
||||
};
|
||||
|
||||
$this->validationWarning($drop_column, $event, $value, $request);
|
||||
}
|
||||
}
|
||||
|
||||
public function setColumnValidations($drop_column, $event, $value)
|
||||
{
|
||||
if (! isset($this->column_validations[$value])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$column_validation = $this->column_validations[$value];
|
||||
|
||||
// set dropdown list for first data row
|
||||
$validation = $event->sheet->getCell("{$drop_column}2")->getDataValidation();
|
||||
|
||||
$validation->setType($column_validation['type'] ?? DataValidation::TYPE_LIST);
|
||||
|
||||
if (empty($column_validation['hide_prompt'])) {
|
||||
$validation->setAllowBlank($column_validation['allow_blank'] ?? false);
|
||||
$validation->setShowInputMessage($column_validation['show_input_message'] ?? true);
|
||||
$validation->setPromptTitle($column_validation['prompt_title'] ?? null);
|
||||
$validation->setPrompt($column_validation['prompt'] ?? null);
|
||||
}
|
||||
|
||||
if (empty($column_validation['hide_error'])) {
|
||||
$validation->setErrorStyle($column_validation['error_style'] ?? DataValidation::STYLE_INFORMATION);
|
||||
$validation->setShowErrorMessage($column_validation['show_error_message'] ?? true);
|
||||
$validation->setErrorTitle($column_validation['error_title'] ?? null);
|
||||
$validation->setError($column_validation['error'] ?? null);
|
||||
}
|
||||
|
||||
if (! empty($column_validation['options'])) {
|
||||
$validation->setFormula1(sprintf('"%s"', implode(',', $column_validation['options'])));
|
||||
$validation->setShowDropDown($column_validation['show_dropdown'] ?? true);
|
||||
}
|
||||
|
||||
// clone validation to remaining rows
|
||||
for ($i = 3; $i <= $this->row_count; $i++) {
|
||||
$event->sheet->getCell("{$drop_column}{$i}")->setDataValidation(clone $validation);
|
||||
}
|
||||
|
||||
// set columns to autosize
|
||||
for ($i = 1; $i <= $this->column_count; $i++) {
|
||||
$column = Coordinate::stringFromColumnIndex($i);
|
||||
$event->sheet->getColumnDimension($column)->setAutoSize(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validationWarning($drop_column, $event, $value, $request)
|
||||
{
|
||||
$rules = $this->prepareRules($request->rules());
|
||||
|
||||
if (! isset($rules[$value])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$rule = explode('|', $rules[$value]);
|
||||
|
||||
$prompt = '';
|
||||
|
||||
foreach ($rule as $r) {
|
||||
if (strpos($r, 'unique') !== false) {
|
||||
$r = 'unique';
|
||||
}
|
||||
|
||||
if (strpos($r, 'amount') !== false) {
|
||||
$r = 'double';
|
||||
}
|
||||
|
||||
if (strpos($r, 'date_format') !== false) {
|
||||
$prompt = $prompt . trans('validation.date_format', [
|
||||
'attribute' => $value,
|
||||
'format' => str_replace('date_format:', '', $r)
|
||||
]) . ' ';
|
||||
}
|
||||
|
||||
if (strpos($r, 'required_without') !== false) {
|
||||
$prompt = $prompt . trans('validation.required_without', [
|
||||
'attribute' => $value,
|
||||
'values' => str_replace('required_without:', '', $r)
|
||||
]) . ' ';
|
||||
}
|
||||
|
||||
if (in_array($r, ['required', 'email', 'integer', 'unique', 'date_format', 'double'])) {
|
||||
$prompt = $prompt . trans('validation.' . $r, ['attribute' => $value]) . ' ';
|
||||
}
|
||||
}
|
||||
|
||||
$validation = $event->sheet->getCell("{$drop_column}2")->getDataValidation();
|
||||
|
||||
$validation->setAllowBlank(false);
|
||||
$validation->setShowInputMessage(true);
|
||||
$validation->setPromptTitle(trans('general.validation_warning'));
|
||||
$validation->setPrompt($prompt ?? null);
|
||||
|
||||
for ($i = 3; $i <= $this->row_count; $i++) {
|
||||
$event->sheet->getCell("{$drop_column}{$i}")->setDataValidation(clone $validation);
|
||||
}
|
||||
|
||||
for ($i = 1; $i <= $this->column_count; $i++) {
|
||||
$column = Coordinate::stringFromColumnIndex($i);
|
||||
$event->sheet->getColumnDimension($column)->setAutoSize(true);
|
||||
}
|
||||
}
|
||||
|
||||
public function getDropdownOptions($model, $select): array
|
||||
{
|
||||
$limit = 253;
|
||||
$selects = [];
|
||||
$totalLength = 0;
|
||||
|
||||
$model::select($select)->each(function ($row) use (&$selects, &$totalLength, $limit, $select) {
|
||||
$nameLength = mb_strlen($row->$select);
|
||||
|
||||
if ($totalLength + $nameLength <= $limit && $nameLength !== 0) {
|
||||
$selects[] = $row->$select;
|
||||
$totalLength += $nameLength;
|
||||
}
|
||||
});
|
||||
|
||||
return $selects;
|
||||
}
|
||||
|
||||
/**
|
||||
* You can override this method to add custom rules for each row.
|
||||
*/
|
||||
public function prepareRules(array $rules): array
|
||||
{
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function registerEvents(): array
|
||||
{
|
||||
return [
|
||||
AfterSheet::class => function(AfterSheet $event) {
|
||||
$this->afterSheet($event);
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,15 @@ namespace App\Exports\Banking;
|
|||
|
||||
use App\Abstracts\Export;
|
||||
use App\Models\Banking\Transaction as Model;
|
||||
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
|
||||
use App\Http\Requests\Banking\Transaction as Request;
|
||||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
|
||||
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
|
||||
|
||||
class Transactions extends Export implements WithColumnFormatting
|
||||
{
|
||||
public $request_class = Request::class;
|
||||
|
||||
public function collection()
|
||||
{
|
||||
return Model::with('account', 'category', 'contact', 'document')->collectForExport($this->ids, ['paid_at' => 'desc']);
|
||||
|
|
@ -46,6 +50,24 @@ class Transactions extends Export implements WithColumnFormatting
|
|||
];
|
||||
}
|
||||
|
||||
public function columnValidations(): array
|
||||
{
|
||||
return [
|
||||
'type' => [
|
||||
'options' => array_keys(config('type.transaction'))
|
||||
],
|
||||
// 'paid_at' => [
|
||||
// 'type' => DataValidation::TYPE_NONE,
|
||||
// 'prompt_title' => trans('general.validation_warning'),
|
||||
// 'prompt' => trans('validation.date_format', ['attribute' => 'paid_at', 'format' => 'yyyy-mm-dd']),
|
||||
// 'hide_error' => true,
|
||||
// ],
|
||||
// 'contact_email' => [
|
||||
// 'options' => $this->getDropdownOptions(Contact::class, 'email'),
|
||||
// ]
|
||||
];
|
||||
}
|
||||
|
||||
public function columnFormats(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Exports\Banking;
|
||||
|
||||
use App\Abstracts\Export;
|
||||
use App\Http\Requests\Banking\Transfer as Request;
|
||||
use App\Models\Banking\Transfer as Model;
|
||||
use App\Utilities\Date;
|
||||
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
|
||||
|
|
@ -10,6 +11,8 @@ use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
|||
|
||||
class Transfers extends Export implements WithColumnFormatting
|
||||
{
|
||||
public $request_class = Request::class;
|
||||
|
||||
public function collection()
|
||||
{
|
||||
return Model::with(
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@
|
|||
namespace App\Exports\Common\Sheets;
|
||||
|
||||
use App\Abstracts\Export;
|
||||
use App\Http\Requests\Common\ItemTax as Request;
|
||||
use App\Models\Common\ItemTax as Model;
|
||||
|
||||
class ItemTaxes extends Export
|
||||
{
|
||||
public $request_class = Request::class;
|
||||
|
||||
public function collection()
|
||||
{
|
||||
return Model::with('item', 'tax')->collectForExport($this->ids, null, 'item_id');
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@
|
|||
namespace App\Exports\Common\Sheets;
|
||||
|
||||
use App\Abstracts\Export;
|
||||
use App\Http\Requests\Common\Item as Request;
|
||||
use App\Models\Common\Item as Model;
|
||||
|
||||
class Items extends Export
|
||||
{
|
||||
public $request_class = Request::class;
|
||||
|
||||
public function collection()
|
||||
{
|
||||
return Model::with('category')->collectForExport($this->ids);
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@
|
|||
namespace App\Exports\Settings;
|
||||
|
||||
use App\Abstracts\Export;
|
||||
use App\Http\Requests\Setting\Category as Request;
|
||||
use App\Models\Setting\Category as Model;
|
||||
|
||||
class Categories extends Export
|
||||
{
|
||||
public $request_class = Request::class;
|
||||
|
||||
public function collection()
|
||||
{
|
||||
return Model::collectForExport($this->ids);
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@
|
|||
namespace App\Exports\Settings;
|
||||
|
||||
use App\Abstracts\Export;
|
||||
use App\Http\Requests\Setting\Tax as Request;
|
||||
use App\Models\Setting\Tax as Model;
|
||||
|
||||
class Taxes extends Export
|
||||
{
|
||||
public $request_class = Request::class;
|
||||
|
||||
public function collection()
|
||||
{
|
||||
return Model::collectForExport($this->ids);
|
||||
|
|
|
|||
|
|
@ -68,6 +68,26 @@ return [
|
|||
'manager' => '',
|
||||
'company' => '',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Export validations
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Number of rows that will have the dropdown
|
||||
|
|
||||
*/
|
||||
'row_count' => env('EXCEL_EXPORTS_ROW_COUNT', 250),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Export validations
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Number of columns to be auto sized
|
||||
|
|
||||
*/
|
||||
'column_count' => env('EXCEL_EXPORTS_COLUMN_COUNT', 25),
|
||||
],
|
||||
|
||||
'imports' => [
|
||||
|
|
|
|||
|
|
@ -236,6 +236,7 @@ return [
|
|||
'preview_mode' => 'Preview Mode',
|
||||
'go_back' => 'Go back to :type',
|
||||
'validation_error' => 'Validation error',
|
||||
'validation_warning' => 'Validation warning',
|
||||
'dismiss' => 'Dismiss',
|
||||
'size' => 'Size',
|
||||
'media' => 'Media',
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ return [
|
|||
'dimensions' => 'The :attribute has invalid image dimensions.',
|
||||
'distinct' => 'The :attribute field has a duplicate value.',
|
||||
'doesnt_start_with' => 'The :attribute may not start with one of the following: :values.',
|
||||
'double' => 'The :attribute must be a valid double.',
|
||||
'email' => 'The :attribute must be a valid email address.',
|
||||
'ends_with' => 'The :attribute must end with one of the following: :values.',
|
||||
'enum' => 'The selected :attribute is invalid.',
|
||||
|
|
|
|||
Loading…
Reference in New Issue