diff --git a/Gruntfile.js b/Gruntfile.js index 6bfb990c..0ec74228 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -283,7 +283,7 @@ module.exports = function(grunt) { expand: true, cwd: 'build/img', src: ['**'], - dest: 'public/assets/img/' + dest: 'public/img/' }, { expand: true, diff --git a/app/Datatables/Admin/Core/Mail/MailLogsDataTable.php b/app/Datatables/Admin/Core/Mail/MailLogsDataTable.php new file mode 100644 index 00000000..3090dfc6 --- /dev/null +++ b/app/Datatables/Admin/Core/Mail/MailLogsDataTable.php @@ -0,0 +1,53 @@ +buildQuery($model); + } + + public function modifier($datatables) + { + $datatables + ->editColumn('sent_to', function (MailLog $log) { + return MailParser::getToEmail($log->event); + }) + ->editColumn('subject', function (MailLog $log) { + return MailParser::getSubject($log->event); + }) + ->rawColumns(['action']); + + return parent::modifier($datatables); + } + + public function getHtmlButtons() + { + return self::getButtonShow(); + } + + protected function getColumns() + { + return [ + Column::make('created_at')->title(__('sent')), + Column::make('sent_to')->title(__('user')), + Column::make('subject')->title(__('subject')), + $this->makeColumnButtons()->width('60'), + ]; + } +} diff --git a/app/Datatables/Admin/Core/Mail/MailTemplatesDataTable.php b/app/Datatables/Admin/Core/Mail/MailTemplatesDataTable.php new file mode 100644 index 00000000..e0513c80 --- /dev/null +++ b/app/Datatables/Admin/Core/Mail/MailTemplatesDataTable.php @@ -0,0 +1,49 @@ +buildQuery($model); + } + + public function getHtmlButtons() + { + $buttons = ''; + if (Users::hasPermission('mail_templates_view')) { + $buttons .= self::getButtonShow(); + } + if (Users::hasPermission('mail_templates_update')) { + $buttons .= self::getButtonEdit(); + } + if (Users::hasPermission('mail_templates_delete')) { + $buttons .= self::getButtonDel(); + } + + return $buttons; + } + + protected function getColumns() + { + return [ + Column::make('subject')->title(__('Core.subject')), + Column::make('mailable')->title(__('Mailable')), + $this->makeColumnButtons()->width('60'), + ]; + } +} diff --git a/app/Datatables/Shop/ArticleNaturesDataTable.php b/app/Datatables/Shop/ArticleNaturesDataTable.php index 6c78778b..ae61be14 100644 --- a/app/Datatables/Shop/ArticleNaturesDataTable.php +++ b/app/Datatables/Shop/ArticleNaturesDataTable.php @@ -5,6 +5,7 @@ namespace App\Datatables\Shop; use Yajra\DataTables\Html\Column; use App\Datatables\ParentDataTable as DataTable; use App\Models\Shop\ArticleNature; +use App\Repositories\Shop\ArticleNatures; class ArticleNaturesDataTable extends DataTable { @@ -16,11 +17,22 @@ class ArticleNaturesDataTable extends DataTable return $this->buildQuery($model); } + public function modifier($datatables) + { + $datatables + ->editColumn('product_type', function (ArticleNature $nature) { + return ArticleNatures::getProductTypeName($nature->product_type); + }) + ->rawColumns(['action']); + return parent::modifier($datatables); + } + protected function getColumns() { return [ + Column::make('product_type')->title('Famille de produit')->width(140), Column::make('name')->title('Nom'), - Column::make('articles_count')->title('#Art')->addClass('text-right')->searchable(false)->width(60), + Column::make('articles_count')->title('Nb Art.')->addClass('text-right')->searchable(false)->width(60), $this->makeColumnButtons(), ]; } diff --git a/app/Datatables/Shop/InvoicesDataTable.php b/app/Datatables/Shop/InvoicesDataTable.php index f6b50110..f6c9c42d 100644 --- a/app/Datatables/Shop/InvoicesDataTable.php +++ b/app/Datatables/Shop/InvoicesDataTable.php @@ -36,9 +36,9 @@ class InvoicesDataTable extends DataTable protected function getColumns() { return [ - - Column::make('status'), - Column::make('created_at')->title('Date'), + Column::make('ref')->title('Ref')->width(80), + Column::make('status')->width(60), + Column::make('created_at')->title('Date')->width(100), Column::make('customer.last_name')->title('Client')->default(''), Column::make('total')->addClass('text-right'), $this->makeColumnButtons(), diff --git a/app/Datatables/Shop/OrdersDataTable.php b/app/Datatables/Shop/OrdersDataTable.php index 3038b2db..45cde5e2 100644 --- a/app/Datatables/Shop/OrdersDataTable.php +++ b/app/Datatables/Shop/OrdersDataTable.php @@ -44,6 +44,7 @@ class OrdersDataTable extends DataTable protected function getColumns() { return [ + Column::make('ref')->title('Ref'), Column::make('status')->title('Statut'), Column::make('created_at')->title('Date'), Column::make('customer.last_name')->title('Client'), diff --git a/app/Http/Controllers/Admin/Core/Mail/Controller.php b/app/Http/Controllers/Admin/Core/Mail/Controller.php new file mode 100644 index 00000000..1fbaa31e --- /dev/null +++ b/app/Http/Controllers/Admin/Core/Mail/Controller.php @@ -0,0 +1,9 @@ +middleware('ability:admin'); + } + + public function index(MailLogsDataTable $dataTable) + { + return $dataTable->render('admin.Core.Mail.MailLog.index', $data ?? []); + } + + public function show($id) + { + $data['message'] = MailLogs::getParsed($id); + + return view('admin.Core.Mail.MailLog.modal', $data); + } +} diff --git a/app/Http/Controllers/Admin/Core/Mail/MailTemplateController.php b/app/Http/Controllers/Admin/Core/Mail/MailTemplateController.php new file mode 100644 index 00000000..c39195ef --- /dev/null +++ b/app/Http/Controllers/Admin/Core/Mail/MailTemplateController.php @@ -0,0 +1,70 @@ +middleware('ability:admin'); + } + + public function index(MailTemplatesDataTable $dataTable) + { + return $dataTable->render('Admin.Core.Mail.MailTemplate.index', $data ?? []); + } + + public function modalCreate() + { + $data = MailTemplates::init(); + return view('Admin.Core.Mail.MailTemplate.modal', $data ?? []); + } + + public function modalEdit($id = false) + { + $data = MailTemplates::init(); + $data['mail_template'] = MailTemplates::edit($id); + + return view('Admin.Core.Mail.MailTemplate.modal', $data); + } + + public function storeAjax(Request $request) + { + $data = $request->all(); + unset($data['proengsoft_jsvalidation']); + $ret = MailTemplates::store($data); + + return response()->json(['error' => 0]); + } + + public function destroy(Request $request, $id = false) + { + $id = $id ?? $request->input('id'); + MailTemplates::destroy($id); + + return response()->json(['error' => 0]); + } + + public function getVarsByMailable($mailable) + { + $data['vars'] = MailTemplates::getVarsByMailable($mailable); + + return view('Admin.Core.Mail.MailTemplate.partials.vars', $data); + } + + public function preview($template_id, $user_id) + { + return MailTemplates::preview($template_id, $user_id); + } + + public function modalPreview($template_id) + { + $data = MailTemplates::getDataFormodalPreview($template_id); + + return view('Admin.Core.Mail.MailTemplate.partials.modalPreview', $data); + } +} diff --git a/app/Http/Controllers/Admin/Shop/ArticleNatureController.php b/app/Http/Controllers/Admin/Shop/ArticleNatureController.php index 4ff24bfe..770fb728 100644 --- a/app/Http/Controllers/Admin/Shop/ArticleNatureController.php +++ b/app/Http/Controllers/Admin/Shop/ArticleNatureController.php @@ -34,6 +34,9 @@ class ArticleNatureController extends Controller public function edit($id) { $data['article_nature'] = ArticleNatures::get($id); + $data['product_types'] = ArticleNatures::getProductTypes(); + // dump($data); + // exit; return view('Admin.Shop.ArticleNatures.edit', $data); } @@ -42,8 +45,9 @@ class ArticleNatureController extends Controller return ArticleNatures::destroy($id); } - public static function getOptions($product_type) + public static function getOptions(Request $request) { - return response()->json(['0' => ''] + ArticleNatures::getOptionsByProductType($product_type)); + $data = ArticleNatures::getOptionsByProductTypeModel($request->input('product_type')); + return response()->json(['0' => ''] + $data); } } diff --git a/app/Http/Controllers/Shop/ArticleController.php b/app/Http/Controllers/Shop/ArticleController.php index 8ace1f33..1390e1a4 100644 --- a/app/Http/Controllers/Shop/ArticleController.php +++ b/app/Http/Controllers/Shop/ArticleController.php @@ -14,6 +14,7 @@ class ArticleController extends Controller { $data['article'] = Articles::getArticleToSell($id); // $data['breadcrumb'] = Categories::getAncestorsByCategory($category_id); + $data['offers2'] = Articles::getSiblings($id)->toArray(); // dump($data); // exit; return view('Shop.Articles.show', $data); diff --git a/app/Http/Controllers/Shop/CategoryController.php b/app/Http/Controllers/Shop/CategoryController.php index b039b2aa..6c8c9cf9 100644 --- a/app/Http/Controllers/Shop/CategoryController.php +++ b/app/Http/Controllers/Shop/CategoryController.php @@ -10,6 +10,7 @@ use App\Repositories\Shop\Categories; use App\Repositories\Shop\TagGroups; use App\Datatables\Shop\CategoriesDataTable; +use App\Repositories\Shop\ArticleNatures; class CategoryController extends Controller { @@ -18,43 +19,52 @@ class CategoryController extends Controller return $dataTable->render('Shop.Categories.list'); } - public function show(Request $request, $category_id) + public function show(Request $request, $category_id, $article_nature_id = false) { - switch ($request->input('article_nature')) { - case 'semences': - $product_type = 'botanic'; - $article_nature_id = 1; - break; - case 'plants': - $product_type = 'botanic'; - $article_nature_id = 2; - break; - case 'legumes': - $product_type = 'botanic'; - $article_nature_id = 3; - break; - default: - $product_type = 'botanic'; - $article_nature_id = 1; - break; + if ($article_nature_id) { + $product_type = ArticleNatures::getProductType($article_nature_id); + dump($product_type); + exit; + } else { + // $product_type = Articles::getProductTypeByCategory($category_id); + // dump($product_type); + switch ($request->input('article_nature')) { + case 'semences': + $product_type = 'botanic'; + $article_nature_id = 1; + break; + case 'plants': + $product_type = 'botanic'; + $article_nature_id = 2; + break; + case 'legumes': + $product_type = 'botanic'; + $article_nature_id = 3; + break; + default: + $product_type = 'botanic'; + $article_nature_id = 1; + break; + } + // $product_type = ArticleNatures::getProductType($article_nature_id); + // dump($product_type); } $data = [ 'category' => Categories::getFull($category_id), 'breadcrumb' => Categories::getAncestorsByCategory($category_id), 'display_by_rows' => $request->input('display_by_rows') ?? false, 'product_type' => $product_type, - 'article_nature' => $request->input('article_nature'), + 'article_nature' => $article_nature_id, 'tags_selected' => $request->input('tags') ?? [], 'articles' => Articles::getArticlesToSell([ 'category_id' => $category_id, 'tags' => $request->input('tags') ?? [], - 'product_type' => $product_type, + 'product_type' => $product_type ?? false, 'article_nature_id' => $article_nature_id ?? false, ]), 'tags' => TagGroups::getWithTagsAndCountOffers($category_id), ]; // dump($data); - // exit; return view('Shop.Shelves.shelve', $data); } diff --git a/app/Menu/Contents.php b/app/Menu/Contents.php new file mode 100644 index 00000000..b328a0ff --- /dev/null +++ b/app/Menu/Contents.php @@ -0,0 +1,23 @@ +add('Contenus', ['icon' => 'newspaper' ]) + ->id('contents') + ->order(6); + + $menu->addTo('contents', 'Contenus', [ + 'route' => 'Admin.Shop.Homepages.index', + ])->activeIfRoute(['Admin.Shop.Homepages.*'])->order(1); + + $menu->addTo('contents', 'Template de Mails', [ + 'route' => 'Admin.Core.Mail.MailTemplate.index', + ])->activeIfRoute(['Admin.Core.Mail.MailTemplate.*'])->order(2); + } +} diff --git a/app/Menu/Shop.php b/app/Menu/Shop.php index d448cef7..b8adb5c3 100644 --- a/app/Menu/Shop.php +++ b/app/Menu/Shop.php @@ -55,10 +55,6 @@ class Shop $menu->addTo('shop', 'Unités', [ 'route' => 'Admin.Shop.Unities.index', ])->activeIfRoute(['Admin.Shop.Unities.*'])->order(14); - - $menu->addTo('shop', 'Contenus', [ - 'route' => 'Admin.Shop.Homepages.index', - ])->activeIfRoute(['Admin.Shop.Homepages.*'])->order(15); } } diff --git a/app/Models/Core/Mail/MailLog.php b/app/Models/Core/Mail/MailLog.php new file mode 100644 index 00000000..a7cff37c --- /dev/null +++ b/app/Models/Core/Mail/MailLog.php @@ -0,0 +1,21 @@ +where('sent_to', $email); + } + + public function getCreatedAtAttribute($value) + { + return DateTime::DateTimeToLocale($value); + } +} diff --git a/app/Models/Core/Mail/MailTemplate.php b/app/Models/Core/Mail/MailTemplate.php new file mode 100644 index 00000000..502abf15 --- /dev/null +++ b/app/Models/Core/Mail/MailTemplate.php @@ -0,0 +1,21 @@ +where($this->table . '.product_type', $model); + return $model ? $query->where($this->table . '.product_type', $model) : $query; } - public function scopeByProductId($query, $model_id) + public function scopeByProductId($query, $product_id) { - return $query->where($this->table . '.product_id', $model_id); + return $product_id ? $query->where($this->table . '.product_id', $product_id) : $query; } public function scopeByTag($query, $tag_id) diff --git a/app/Models/Shop/ArticleNature.php b/app/Models/Shop/ArticleNature.php index 490ec75a..4bcf8048 100644 --- a/app/Models/Shop/ArticleNature.php +++ b/app/Models/Shop/ArticleNature.php @@ -25,14 +25,14 @@ class ArticleNature extends Model return $query->where($this->table . '.id', $id); } - public function scopeByBotanic($query); + public function scopeByBotanic($query) { - return $query->where($this->table . '.product_type', 1); + return $query->ByProductType(1); } - public function scopeByMerchandise($query); + public function scopeByMerchandise($query) { - return $query->where($this->table . '.product_type', 2); + return $query->ByProductType(2); } public function scopeByProductType($query, $type) diff --git a/app/Repositories/Core/Export/HelperExcel.php b/app/Repositories/Core/Export/HelperExcel.php new file mode 100644 index 00000000..8829994b --- /dev/null +++ b/app/Repositories/Core/Export/HelperExcel.php @@ -0,0 +1,45 @@ + self::setFill($bgcolor), + 'borders' => self::setBorders($bgcolor), + 'font' => self::setFont($color, 14, true), + ]; + } + + public static function setFill($color) + { + return [ + 'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID, + 'startColor' => [ + 'rgb' => $color, + ], + ]; + } + + public static function setBorders($color) + { + return [ + 'outline' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THICK, + 'color' => ['argb' => $color], + ], + ]; + } + + public static function setFont($color, $size = 12, $bold = false, $font = 'Calibri') + { + return [ + 'name' => $font, + 'size' => $size, + 'bold' => $bold, + 'color' => ['argb' => $color], + ]; + } +} diff --git a/app/Repositories/Core/Mail/MailLogs.php b/app/Repositories/Core/Mail/MailLogs.php new file mode 100644 index 00000000..e0a8f6ea --- /dev/null +++ b/app/Repositories/Core/Mail/MailLogs.php @@ -0,0 +1,26 @@ +event); + } + + public static function getParsed($id) + { + return MailParser::getParsed(self::get($id)->event); + } + + public static function getModel() + { + return MailLog::query(); + } +} diff --git a/app/Repositories/Core/Mail/MailParser.php b/app/Repositories/Core/Mail/MailParser.php new file mode 100644 index 00000000..f412c356 --- /dev/null +++ b/app/Repositories/Core/Mail/MailParser.php @@ -0,0 +1,89 @@ + self::getFromByModel($model), + 'subject' => self::getSubjectByModel($model), + 'content' => self::getHtmlByModel($model), + 'to_name' => self::getToNameByModel($model), + 'to_email' => self::getToEmailByModel($model), + ]; + } + + public static function getSubject($mail) + { + return self::getSubjectByModel(self::getModel($mail)); + } + + public static function getText($mail) + { + return self::getTextByModel(self::getModel($mail)); + } + + public static function getHtml($mail) + { + return self::getHtmlByModel(self::getModel($mail)); + } + + public static function getFrom($mail) + { + return self::getFromByModel(self::getModel($mail)); + } + + public static function getToName($mail) + { + return self::getToNameByModel(self::getModel($mail)); + } + + public static function getToEmail($mail) + { + return self::getToEmailByModel(self::getModel($mail)); + } + + public static function getSubjectByModel($model) + { + return $model->getHeaderValue(HeaderConsts::SUBJECT); + } + + public static function getTextByModel($model) + { + return $model->getTextContent(); + } + + public static function getFromByModel($model) + { + return $model->getHeader(HeaderConsts::FROM)->getPersonName(); + } + + public static function getToNameByModel($model) + { + return $model->getHeader(HeaderConsts::TO)->getAddresses()[0]->getName(); + } + + public static function getToEmailByModel($model) + { + return $model->getHeader(HeaderConsts::TO)->getAddresses()[0]->getEmail(); + } + + public static function getHtmlByModel($model) + { + return $model->getHtmlContent(); + } + + public static function getModel($mail) + { + $mailParser = new MailMimeParser(); + + return $mailParser->parse($mail, false); + } +} diff --git a/app/Repositories/Core/Mail/MailTemplates.php b/app/Repositories/Core/Mail/MailTemplates.php new file mode 100644 index 00000000..2ce1bc93 --- /dev/null +++ b/app/Repositories/Core/Mail/MailTemplates.php @@ -0,0 +1,64 @@ + Mailables::getList(), + ]; + } + + public static function edit($id) + { + $data = self::get($id)->toArray(); + $mailable = $data['mailable']; + $data['vars'] = $mailable::getVariables(); + + return $data; + } + + public static function getVarsByMailable($mailable) + { + return $mailable::getVariables(); + } + + public static function getDataFormodalPreview($id) + { + $template = self::get($id); + $mailable = $template->mailable; + + return [ + 'id' => $id, + 'users' => $mailable::getUsers(), + ]; + } + + public static function preview($id, $user_id) + { + $template = self::get($id); + $mailable = $template->mailable; + $data = $mailable::getDataByUser($user_id); + $html_template = $template->toArray()['html_template_translations'][$data['lang']] ?? false; + if ($html_template) { + $m = new Mustache_Engine(); + + return $m->render($html_template, $data); + } else { + return false; + } + } + + public static function getModel() + { + return MailTemplate::query(); + } +} diff --git a/app/Repositories/Core/Mail/Mailables.php b/app/Repositories/Core/Mail/Mailables.php new file mode 100644 index 00000000..2feca7ba --- /dev/null +++ b/app/Repositories/Core/Mail/Mailables.php @@ -0,0 +1,18 @@ +pluck('name', 'id')->toArray(); } - public static function getOptionsByMerchandise() + public static function getProductType($id) { - return self::getOptionsByProductType(2); + $type = self::get($id)->product_type ?? false; + return $type ? self::getProductTypes()[$type] : false; + } + + public static function getProductTypeName($type) + { + return self::getProductTypes()[$type] ?? false; + } + + public static function getProductTypeByModel($model) + { + switch ($model) { + case Specie::class: + $type = 1; + break; + case Variety::class: + $type = 1; + break; + case Merchandise::class: + $type = 2; + break; + } + return $type ?? false; + } + + public static function getProductTypes() + { + return ['', 'botanic', 'merchandise']; } public static function getOptionsByBotanic() @@ -21,9 +52,30 @@ class ArticleNatures return self::getOptionsByProductType(1); } + public static function getOptionsByMerchandise() + { + return self::getOptionsByProductType(2); + } + + public static function getOptionsByProductTypeModel($model) + { + $type = self::getProductTypeByModel($model); + return self::getOptionsByProductType($type); + } + public static function getOptionsByProductType($type) { - return ArticleNature::byProductType($type)->get()->pluck('name', 'id')->toArray(); + return self::getByProductType($type)->pluck('name', 'id')->toArray(); + } + + public static function getByProductType($type) + { + return ArticleNature::byProductType($type)->get(); + } + + public static function getByCategory($category_id) + { + return Article::byCategory($category_id)->select('article_nature_id')->distinct()->get(); } public static function getAll() diff --git a/app/Repositories/Shop/Articles.php b/app/Repositories/Shop/Articles.php index 2c8ae824..d4323f66 100644 --- a/app/Repositories/Shop/Articles.php +++ b/app/Repositories/Shop/Articles.php @@ -10,6 +10,7 @@ use App\Repositories\Core\Comments; use App\Repositories\Botanic\Species; use App\Repositories\Botanic\Varieties; use App\Models\Shop\Article; +use App\Models\Shop\Merchandise; use App\Traits\Repository\Imageable; @@ -106,7 +107,7 @@ class Articles $data['description'] = self::getFullDescriptionByArticle($article); $images = self::getFullImagesByArticle($article); $data['image'] = self::getPreviewSrc($images[0] ?? false); - $data['images'] = $images; + $data['images'] = count($images) ? $images : false; $data['image_big'] = self::getImageSrc($images[0] ?? false); $data['inherited'] = self::getInherited($id); $data['categories'] = self::getCategoriesNameByArticle($article); @@ -376,6 +377,22 @@ class Articles return $article->categories->pluck('id')->toArray(); } + public static function getProductTypeByCategory($category_id) + { + $models = self::getProductTypesModelsByCategory($category_id); + return (($models[0] ?? false) == Merchandise::class) ? 'merchandise' : 'botanic'; + } + + public static function getProductTypesModelsByCategory($category_id) + { + return Article::byCategory($category_id)->select('product_type')->distinct()->get(); + } + + public static function countProductTypesByCategory($category_id) + { + return Article::byCategory($category_id)->select('product_type')->distinct()->count(); + } + public static function getCategoriesNameByArticle($article) { return $article->categories->pluck('name', 'id')->toArray(); diff --git a/app/Repositories/Shop/Orders.php b/app/Repositories/Shop/Orders.php index 91f7aa3b..acbc6739 100644 --- a/app/Repositories/Shop/Orders.php +++ b/app/Repositories/Shop/Orders.php @@ -4,6 +4,7 @@ namespace App\Repositories\Shop; use Carbon\Carbon; use App\Models\Shop\Order; +use Illuminate\Support\Str; class Orders { @@ -70,6 +71,8 @@ class Orders public static function create($data) { OrderStats::increase(); + $data['uuid'] = Str::uuid()->toString(); + $data['ref'] = self::getNewRef(); return Order::create($data); } @@ -111,4 +114,12 @@ class Orders { return ['', 'CARTE BANCAIRE', 'CHEQUE', 'VIREMENT BANCAIRE']; } + + public static function getNewRef() + { + $ref = date('ym') . '00000'; + $last_ref = Order::orderBy('ref', 'desc')->where('ref', '>', $ref)->first(); + return $last_ref ? $last_ref->ref + 1 : $ref + 1; + } + } diff --git a/app/Traits/Model/Basic.php b/app/Traits/Model/Basic.php new file mode 100644 index 00000000..42e3e2c9 --- /dev/null +++ b/app/Traits/Model/Basic.php @@ -0,0 +1,127 @@ + ! self::getField($id, $field)], $id); + } + + public static function getIDs() + { + return self::getAll()->pluck('id'); + } + + public static function getOptions($field = 'name') + { + $data = self::getModel()->pluck($field, 'id')->toArray(); + asort($data, SORT_NATURAL | SORT_FLAG_CASE); + + return $data; + } + + public static function getName($id) + { + return self::getField($id, 'name'); + } + + public static function getByUUID($uuid) + { + return self::getByField('uuid', $uuid)->first(); + } + + public static function getFields($field) + { + return self::getAll()->pluck($field); + } + + public static function getByField($field, $value) + { + return self::getModel()->where($field, $value); + } + + public static function getField($id, $field) + { + $model = self::get($id); + + return $model ? $model->$field : false; + } + + public static function edit($id) + { + return self::get($id)->toArray(); + } + + public static function store($data) + { + return ($data['id'] ?? false) ? self::update($data) : self::create($data); + } + + public static function create($data) + { + return self::getModel()->create($data); + } + + public static function update($data, $id = false) + { + $id = $id ? $id : $data['id']; + $model = self::get($id); + $model->update($data); + + return $model; + } + + public static function destroy($id) + { + $model = self::get($id); + + return $model ? $model->delete() : false; + } + + public static function count() + { + return self::getModel()->count(); + } + + public static function firstOrCreate($search, $data) + { + return self::getModel()::firstOrCreate($search, $data); + } + + public static function get($id, $relations = false, $relations_count = false) + { + return self::getModelRelations($relations, $relations_count)->find($id); + } + + public static function getAll($relations = false, $relations_count = false) + { + return self::getModelRelations($relations, $relations_count)->get(); + } + + public static function getModelRelations($relations = false, $relations_count = false) + { + $model = $relations ? self::getModelWithRelations($relations) : false; + $model = $relations_count ? self::getModelWithCountRelations($relations_count, $model) : $model; + + return $model ? $model : self::getModel(); + } + + public static function getModelWithRelations($relations = false, $model = false) + { + return is_object($model) ? $model->with($relations) : self::getModel()->with($relations); + } + + public static function getModelWithCountRelations($relations = false, $model = false) + { + return is_object($model) ? $model->withCount($relations) : self::getModel()->withCount($relations); + } + + public static function getModel(): Model + { + return new Model(); + } +} diff --git a/app/Traits/Repository/Imageable.php b/app/Traits/Repository/Imageable.php index 4dbfcc96..4fca96a8 100644 --- a/app/Traits/Repository/Imageable.php +++ b/app/Traits/Repository/Imageable.php @@ -35,7 +35,7 @@ trait Imageable public static function getPreviewSrc($image, $with_undefined = true) { - return $image ? Medias::getPreviewSrc($image) : ($with_undefined ? '/img/visuel-non-disponible.jpg' : ''); + return $image ? Medias::getPreviewSrc($image) : ($with_undefined ? self::getUnknown() : ''); } public static function getNormal($image, $with_undefined = true) @@ -46,7 +46,7 @@ trait Imageable public static function getNormalSrc($image, $with_undefined = true) { - return $image ? Medias::getNormalSrc($image) : ($with_undefined ? '/img/visuel-non-disponible.jpg' : ''); + return $image ? Medias::getNormalSrc($image) : ($with_undefined ? self::getUnknown() : ''); } public static function getImage($image, $with_undefined = true) @@ -57,7 +57,12 @@ trait Imageable public static function getImageSrc($image, $with_undefined = true) { - return $image ? Medias::getImageSrc($image) : ($with_undefined ? '/img/visuel-non-disponible.jpg' : ''); + return $image ? Medias::getImageSrc($image) : ($with_undefined ? self::getUnknown() : ''); + } + + public static function getUnknown() + { + return '/img/visuel-non-disponible.jpg'; } public static function deleteImage($id, $index) diff --git a/build/css/site.css b/build/css/site.css index bd3c5a29..b435b173 100644 --- a/build/css/site.css +++ b/build/css/site.css @@ -87,10 +87,6 @@ label { background-color: #335012; } -a.nav-link { - color: #FFF; -} - .bg-green-ultra-dark { background: linear-gradient(to left top, #102723, #112723, #122724, #122724, #132724); color: #a5b94f; @@ -213,8 +209,18 @@ div.megamenu ul.megamenu li.megamenu.level1 cursor: pointer; } -.dropdown.megamenu a:hover, .dropdown.megamenu a:active, .dropdown.megamenu div.w-100:hover { - background-color: #F2B90F; +#navbarContent > ul > li:hover +{ + border-bottom: 4px solid #FFF!important; +} + +.dropdown-menu a > div.w-100:hover +{ + background-color: #F2B90F; +} + +a.nav-link { + color: #FFF; } .slick-prev:before, .slick-next:before { diff --git a/build/img/article_natures/legumes.png b/build/img/article_natures/legumes.png new file mode 100644 index 00000000..c0c70f67 Binary files /dev/null and b/build/img/article_natures/legumes.png differ diff --git a/build/img/article_natures/plants.png b/build/img/article_natures/plants.png new file mode 100644 index 00000000..ab197eec Binary files /dev/null and b/build/img/article_natures/plants.png differ diff --git a/build/img/article_natures/semences.png b/build/img/article_natures/semences.png new file mode 100644 index 00000000..5090501d Binary files /dev/null and b/build/img/article_natures/semences.png differ diff --git a/build/img/header/basket.svg b/build/img/header/basket.svg new file mode 100644 index 00000000..fd72fcf4 --- /dev/null +++ b/build/img/header/basket.svg @@ -0,0 +1,16 @@ + + diff --git a/build/img/header/catalogue.svg b/build/img/header/catalogue.svg new file mode 100644 index 00000000..777e219e --- /dev/null +++ b/build/img/header/catalogue.svg @@ -0,0 +1,42 @@ + + diff --git a/build/img/header/login.svg b/build/img/header/login.svg new file mode 100644 index 00000000..f07741dc --- /dev/null +++ b/build/img/header/login.svg @@ -0,0 +1,29 @@ + + diff --git a/build/img/visuel-non-disponible.jpg b/build/img/visuel-non-disponible.jpg index 4d458be6..1cd5304d 100644 Binary files a/build/img/visuel-non-disponible.jpg and b/build/img/visuel-non-disponible.jpg differ diff --git a/build/img/watermark.png b/build/img/watermark.png new file mode 100644 index 00000000..e6269473 Binary files /dev/null and b/build/img/watermark.png differ diff --git a/composer.json b/composer.json index ef9924d3..e30ca2e7 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,6 @@ "balping/laravel-hashslug": "^2.2", "barryvdh/laravel-dompdf": "^0.9", "barryvdh/laravel-snappy": "^0.4.7", - "box/spout": "^3.3", "browner12/helpers": "^3.0", "cesargb/laravel-cascade-delete": "^1.2", "coduo/php-humanizer": "^4.0", @@ -26,9 +25,10 @@ "darryldecode/cart": "^4.1", "datatables/datatables": "^1.10", "ddzobov/laravel-pivot-softdeletes": "^2.1", + "dmcbrn/laravel-email-database-log": "^5.2", "dompdf/dompdf": "^1.0.2", "dyrynda/laravel-cascade-soft-deletes": "^4.1", - "eduardokum/laravel-mail-auto-embed": "^1.0", + "eduardokum/laravel-mail-auto-embed": "^2.0", "erjanmx/laravel-migrate-check": "^2.1", "fico7489/laravel-eloquent-join": "^4.1", "fideloper/proxy": "^4.0", @@ -69,7 +69,6 @@ "proengsoft/laravel-jsvalidation": "^4.5", "protonemedia/laravel-cross-eloquent-search": "^3.0", "protonemedia/laravel-eloquent-where-not": "^1.2", - "qoraiche/laravel-mail-editor": "^3.2", "rahul900day/laravel-captcha": "^1.0", "ralphjsmit/laravel-seo": "^1.0", "reedware/laravel-relation-joins": "^3.0", @@ -87,15 +86,18 @@ "spatie/laravel-backup": "^7.0", "spatie/laravel-collection-macros": "^7.12", "spatie/laravel-cookie-consent": "^3.2", + "spatie/laravel-database-mail-templates": "^3.5", "spatie/laravel-mail-preview": "^4.0", "spatie/laravel-medialibrary": "^9.6", "spatie/laravel-stats": "^2.0", "staudenmeir/belongs-to-through": "^2.11", "staudenmeir/eloquent-has-many-deep": "^1.13", "stillat/numeral.php": "^2.0", + "symfony/http-client": "^6.2", "thomasjohnkane/snooze": "^2.2", "toin0u/geocoder-laravel": "^4.2", "unicodeveloper/laravel-password": "^1.0", + "unisharp/laravel-filemanager": "^2.5", "venturecraft/revisionable": "^1.39", "watson/rememberable": "^5.0", "wildside/userstamps": "^2.1", @@ -110,7 +112,7 @@ "facade/ignition": "^2.9", "fakerphp/faker": "^1.13", "fossbarrow/laravel-phpcs": "dev-main", - "imanghafoori/laravel-microscope": "^1.0", + "imanghafoori/laravel-microscope": "1.0.278", "kevincobain2000/laravel-erd": "^1.3", "mockery/mockery": "^1.4.2", "nunomaduro/collision": "^5.4", @@ -133,7 +135,8 @@ "sort-packages": true, "allow-plugins": { "pestphp/pest-plugin": true, - "dealerdirect/phpcodesniffer-composer-installer": true + "dealerdirect/phpcodesniffer-composer-installer": true, + "php-http/discovery": true } }, "extra": { diff --git a/database/migrations/2018_10_10_000000_create_mail_templates_table.php b/database/migrations/2018_10_10_000000_create_mail_templates_table.php new file mode 100644 index 00000000..986fa4f9 --- /dev/null +++ b/database/migrations/2018_10_10_000000_create_mail_templates_table.php @@ -0,0 +1,24 @@ +increments('id'); + $table->string('mailable'); + $table->json('subject')->nullable(); + $table->json('html_template'); + $table->json('text_template')->nullable(); + $table->unsignedInteger('created_by')->nullable(); + $table->unsignedInteger('updated_by')->nullable(); + $table->unsignedInteger('deleted_by')->nullable(); + $table->timestamps(); + $table->softDeletes(); + }); + } +} diff --git a/package.json b/package.json index a62e5c43..06bdd984 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "font-awesome": "^4.7.0", "formBuilder": "^3.2.3", "formiojs": "^4.11.2", + "gasparesganga-jquery-loading-overlay": "^2.1.7", "grunt": "^1.0.4", "grunt-contrib-clean": "^2.0.0", "grunt-contrib-concat": "^1.0.1", @@ -102,6 +103,7 @@ "jquery-json": "^2.6.0", "jquery-migrate": "^3.3.1", "jquery-placeholder": "^2.3.1", + "jquery-plainoverlay": "^1.0.1", "jquery-serializejson": "^3.2.0", "jquery-slidePanel": "^0.3.5", "jquery-slimscroll": "^1.3.8", diff --git a/resources/views/Admin/Core/Mail/MailLog/index.blade.php b/resources/views/Admin/Core/Mail/MailLog/index.blade.php new file mode 100644 index 00000000..84430036 --- /dev/null +++ b/resources/views/Admin/Core/Mail/MailLog/index.blade.php @@ -0,0 +1,38 @@ +@extends('layout.index', [ + 'title' => __('Admin.mail_logs.title'), + 'subtitle' => __('Admin.mail_logs.list'), +]) + +@section('content') + @component('components.card') + @include('components.datatable', [ + 'route' => route('Admin.Core.Mail.MailLog.index'), + 'model' => 'mail_logs', + 'with_add' => false, + 'with_print' => false, + 'with_filters' => true, + 'show_callback' => 'MailLogShow(id);', + ]) + @endcomponent + + @component('components.layout.modal-filters', ['title' => 'Filters', 'id' => 'modal-mail_logs-filters']) + @include('admin.Core.Mail.MailLog.partials.filters', ['model' => 'mail_logs']) + @endcomponent + +@endsection + +@include('load.form.select2') + +@push('js') + +@endpush diff --git a/resources/views/Admin/Core/Mail/MailLog/modal.blade.php b/resources/views/Admin/Core/Mail/MailLog/modal.blade.php new file mode 100644 index 00000000..7b0e681d --- /dev/null +++ b/resources/views/Admin/Core/Mail/MailLog/modal.blade.php @@ -0,0 +1,16 @@ +
+
+
+ 