#3025 Making the announcement status flexible.

This commit is contained in:
Diatrex 2021-02-24 12:17:46 +03:00
parent 228b529728
commit 0a1c83d0dd
18 changed files with 174 additions and 277 deletions

View File

@ -279,6 +279,17 @@ return [
'yes' => [ 'yes' => [
'name' => 'Yes' 'name' => 'Yes'
], ],
'no' => [
'name' => 'No'
],
'is_system' => [
'name' => 'Is System',
'instructions' => 'System status are required and should not be changed',
],
'user_access' => [
'name' => 'User Access',
'instructions' => 'Can a user use this status on his ads?',
],
"no_location" => "No location is selected.", "no_location" => "No location is selected.",
"continue" => 'Continue', "continue" => 'Continue',
"gallery" => 'Gallery', "gallery" => 'Gallery',

View File

@ -30,4 +30,5 @@ return [
'approve_status_change' => "Your Ad's Status Has Been Set to Active!", 'approve_status_change' => "Your Ad's Status Has Been Set to Active!",
'passive_status_change' => "Your Ad's Status Has Been Set to Passive!", 'passive_status_change' => "Your Ad's Status Has Been Set to Passive!",
'sold_status_change' => "Your Ad's Status Has Been Set to Sold!", 'sold_status_change' => "Your Ad's Status Has Been Set to Sold!",
'status_change' => "Your Ad's Status Has Been Set to :status!",
]; ];

View File

@ -411,4 +411,9 @@ class AdvModel extends AdvsAdvsEntryModel implements AdvInterface
'publish_at' => date('Y-m-d H:i:s') 'publish_at' => date('Y-m-d H:i:s')
]); ]);
} }
public function changeStatus($status)
{
$this->update(['status' => $status]);
}
} }

View File

@ -87,4 +87,6 @@ interface AdvInterface extends EntryInterface
public function getStatus(); public function getStatus();
public function approve(); public function approve();
public function changeStatus($status);
} }

View File

@ -1,11 +1,14 @@
<?php namespace Visiosoft\AdvsModule\Adv\Form; <?php namespace Visiosoft\AdvsModule\Adv\Form;
use Visiosoft\AdvsModule\Adv\Event\ReadySimpleAdvFormFields; use Visiosoft\AdvsModule\Adv\Event\ReadySimpleAdvFormFields;
use Visiosoft\AdvsModule\Status\Contract\StatusRepositoryInterface;
class SimpleAdvFormFields class SimpleAdvFormFields
{ {
public function handle(SimpleAdvFormBuilder $builder) public function handle(SimpleAdvFormBuilder $builder, StatusRepositoryInterface $statusRepository)
{ {
$statuses = $statusRepository->all()->pluck('name', 'slug')->all();
$form_fields = [ $form_fields = [
'name', 'name',
'price', 'price',
@ -23,6 +26,13 @@ class SimpleAdvFormFields
'cat10', 'cat10',
'is_get_adv', 'is_get_adv',
'stock', 'stock',
'status' => [
'type' => 'anomaly.field_type.select',
"config" => [
"options" => $statuses,
"mode" => "search",
]
],
'files', 'files',
]; ];

View File

@ -18,7 +18,7 @@ class SimpleAdvFormHandler
$builder->saveForm(); $builder->saveForm();
$ad = $advRepository->find($builder->getFormEntryId()); $ad = $advRepository->find($builder->getFormEntryId());
if ($ad->status !== 'approved') { if (!$builder->getFormValue('status') && $ad->status !== 'approved') {
$ad->approve(); $ad->approve();
} }

View File

@ -3,6 +3,7 @@
use Anomaly\FilesModule\File\FileModel; use Anomaly\FilesModule\File\FileModel;
use Anomaly\Streams\Platform\Addon\AddonCollection; use Anomaly\Streams\Platform\Addon\AddonCollection;
use Anomaly\Streams\Platform\Addon\AddonServiceProvider; use Anomaly\Streams\Platform\Addon\AddonServiceProvider;
use Anomaly\Streams\Platform\Model\Advs\AdvsStatusEntryModel;
use Anomaly\Streams\Platform\Model\Location\LocationVillageEntryModel; use Anomaly\Streams\Platform\Model\Location\LocationVillageEntryModel;
use Anomaly\Streams\Platform\Ui\Table\Event\TableIsQuerying; use Anomaly\Streams\Platform\Ui\Table\Event\TableIsQuerying;
use Visiosoft\AdvsModule\Adv\Contract\AdvRepositoryInterface; use Visiosoft\AdvsModule\Adv\Contract\AdvRepositoryInterface;
@ -21,6 +22,9 @@ use Visiosoft\AdvsModule\Productoption\Contract\ProductoptionRepositoryInterface
use Visiosoft\AdvsModule\Productoption\ProductoptionRepository; use Visiosoft\AdvsModule\Productoption\ProductoptionRepository;
use Visiosoft\AdvsModule\ProductoptionsValue\Contract\ProductoptionsValueRepositoryInterface; use Visiosoft\AdvsModule\ProductoptionsValue\Contract\ProductoptionsValueRepositoryInterface;
use Visiosoft\AdvsModule\ProductoptionsValue\ProductoptionsValueRepository; use Visiosoft\AdvsModule\ProductoptionsValue\ProductoptionsValueRepository;
use Visiosoft\AdvsModule\Status\Contract\StatusRepositoryInterface;
use Visiosoft\AdvsModule\Status\StatusModel;
use Visiosoft\AdvsModule\Status\StatusRepository;
use Visiosoft\LocationModule\Village\Contract\VillageRepositoryInterface; use Visiosoft\LocationModule\Village\Contract\VillageRepositoryInterface;
use Visiosoft\LocationModule\Village\VillageRepository; use Visiosoft\LocationModule\Village\VillageRepository;
use Visiosoft\LocationModule\Village\VillageModel; use Visiosoft\LocationModule\Village\VillageModel;
@ -229,6 +233,12 @@ class AdvsModuleServiceProvider extends AddonServiceProvider
'admin/advs/product_options' => 'Visiosoft\AdvsModule\Http\Controller\Admin\ProductoptionsController@index', 'admin/advs/product_options' => 'Visiosoft\AdvsModule\Http\Controller\Admin\ProductoptionsController@index',
'admin/advs/product_options/create' => 'Visiosoft\AdvsModule\Http\Controller\Admin\ProductoptionsController@create', 'admin/advs/product_options/create' => 'Visiosoft\AdvsModule\Http\Controller\Admin\ProductoptionsController@create',
'admin/advs/product_options/edit/{id}' => 'Visiosoft\AdvsModule\Http\Controller\Admin\ProductoptionsController@edit', 'admin/advs/product_options/edit/{id}' => 'Visiosoft\AdvsModule\Http\Controller\Admin\ProductoptionsController@edit',
// StatusController
'ad/{ad_id}/change-status/{status_id}' => [
'as' => 'visiosoft.module.advs::ad.change.status',
'uses' => 'Visiosoft\AdvsModule\Http\Controller\StatusController@change'
],
]; ];
protected $middleware = [ protected $middleware = [
@ -245,6 +255,7 @@ class AdvsModuleServiceProvider extends AddonServiceProvider
protected $bindings = [ protected $bindings = [
LocationVillageEntryModel::class => VillageModel::class, LocationVillageEntryModel::class => VillageModel::class,
AdvsAdvsEntryModel::class => AdvModel::class, AdvsAdvsEntryModel::class => AdvModel::class,
AdvsStatusEntryModel::class => StatusModel::class,
'my_form' => AdvFormBuilder::class, 'my_form' => AdvFormBuilder::class,
]; ];
@ -257,6 +268,7 @@ class AdvsModuleServiceProvider extends AddonServiceProvider
ProductoptionRepositoryInterface::class => ProductoptionRepository::class, ProductoptionRepositoryInterface::class => ProductoptionRepository::class,
OptionConfigurationRepositoryInterface::class => OptionConfigurationRepository::class, OptionConfigurationRepositoryInterface::class => OptionConfigurationRepository::class,
ProductoptionsValueRepositoryInterface::class => ProductoptionsValueRepository::class, ProductoptionsValueRepositoryInterface::class => ProductoptionsValueRepository::class,
StatusRepositoryInterface::class => StatusRepository::class,
]; ];
public function boot(AddonCollection $addonCollection, FileModel $fileModel) public function boot(AddonCollection $addonCollection, FileModel $fileModel)

View File

@ -1,43 +1,33 @@
<?php namespace Visiosoft\AdvsModule\Http\Controller\Admin; <?php namespace Visiosoft\AdvsModule\Http\Controller\Admin;
use Visiosoft\AdvsModule\Status\Contract\StatusRepositoryInterface;
use Visiosoft\AdvsModule\Status\Form\StatusFormBuilder; use Visiosoft\AdvsModule\Status\Form\StatusFormBuilder;
use Visiosoft\AdvsModule\Status\Table\StatusTableBuilder; use Visiosoft\AdvsModule\Status\Table\StatusTableBuilder;
use Anomaly\Streams\Platform\Http\Controller\AdminController; use Anomaly\Streams\Platform\Http\Controller\AdminController;
class StatusController extends AdminController class StatusController extends AdminController
{ {
/**
* Display an index of existing entries.
*
* @param StatusTableBuilder $table
* @return \Symfony\Component\HttpFoundation\Response
*/
public function index(StatusTableBuilder $table) public function index(StatusTableBuilder $table)
{ {
return $table->render(); return $table->render();
} }
/**
* Create a new entry.
*
* @param StatusFormBuilder $form
* @return \Symfony\Component\HttpFoundation\Response
*/
public function create(StatusFormBuilder $form) public function create(StatusFormBuilder $form)
{ {
return $form->render(); return $form->render();
} }
/** public function edit(StatusFormBuilder $form, StatusRepositoryInterface $statusRepository, $id)
* Edit an existing entry.
*
* @param StatusFormBuilder $form
* @param $id
* @return \Symfony\Component\HttpFoundation\Response
*/
public function edit(StatusFormBuilder $form, $id)
{ {
$status = $statusRepository->find($id);
if ($status->is_system) {
$form->skipField('user_access');
}
$form->skipField('is_system');
$form->skipField('slug');
return $form->render($id); return $form->render($id);
} }
} }

View File

@ -0,0 +1,37 @@
<?php namespace Visiosoft\AdvsModule\Http\Controller;
use Anomaly\Streams\Platform\Http\Controller\PublicController;
use Visiosoft\AdvsModule\Adv\Contract\AdvRepositoryInterface;
use Visiosoft\AdvsModule\Status\Contract\StatusRepositoryInterface;
class StatusController extends PublicController
{
private $advRepository;
private $statusRepository;
public function __construct(AdvRepositoryInterface $advRepository, StatusRepositoryInterface $statusRepository)
{
parent::__construct();
$this->advRepository = $advRepository;
$this->statusRepository = $statusRepository;
}
public function change($adID, $statusID)
{
$ad = $this->advRepository->find($adID);
$status = $this->statusRepository->find($statusID);
if (!$ad || !$status) {
abort(404);
}
$ad->changeStatus($status->slug);
$this->messages->success(trans(
'visiosoft.module.advs::message.status_change',
['status' => $status->name]
));
return redirect()->back();
}
}

View File

@ -4,5 +4,5 @@ use Anomaly\Streams\Platform\Entry\Contract\EntryRepositoryInterface;
interface StatusRepositoryInterface extends EntryRepositoryInterface interface StatusRepositoryInterface extends EntryRepositoryInterface
{ {
public function getUserAccessibleStatuses();
} }

View File

@ -4,63 +4,7 @@ use Anomaly\Streams\Platform\Ui\Form\FormBuilder;
class StatusFormBuilder extends FormBuilder class StatusFormBuilder extends FormBuilder
{ {
/**
* The form fields.
*
* @var array|string
*/
protected $fields = [];
/**
* Additional validation rules.
*
* @var array|string
*/
protected $rules = [];
/**
* Fields to skip.
*
* @var array|string
*/
protected $skips = [];
/**
* The form actions.
*
* @var array|string
*/
protected $actions = [];
/**
* The form buttons.
*
* @var array|string
*/
protected $buttons = [ protected $buttons = [
'cancel', 'cancel',
]; ];
/**
* The form options.
*
* @var array
*/
protected $options = [];
/**
* The form sections.
*
* @var array
*/
protected $sections = [];
/**
* The form assets.
*
* @var array
*/
protected $assets = [];
} }

View File

@ -5,21 +5,15 @@ use Anomaly\Streams\Platform\Entry\EntryRepository;
class StatusRepository extends EntryRepository implements StatusRepositoryInterface class StatusRepository extends EntryRepository implements StatusRepositoryInterface
{ {
/**
* The entry model.
*
* @var StatusModel
*/
protected $model; protected $model;
/**
* Create a new StatusRepository instance.
*
* @param StatusModel $model
*/
public function __construct(StatusModel $model) public function __construct(StatusModel $model)
{ {
$this->model = $model; $this->model = $model;
} }
public function getUserAccessibleStatuses()
{
return $this->newQuery()->where(['is_system' => 0, 'user_access' => 1])->get();
}
} }

View File

@ -4,60 +4,11 @@ use Anomaly\Streams\Platform\Ui\Table\TableBuilder;
class StatusTableBuilder extends TableBuilder class StatusTableBuilder extends TableBuilder
{ {
/**
* The table views.
*
* @var array|string
*/
protected $views = [];
/**
* The table filters.
*
* @var array|string
*/
protected $filters = [];
/**
* The table columns.
*
* @var array|string
*/
protected $columns = [
'name',
];
/**
* The table buttons.
*
* @var array|string
*/
protected $buttons = [ protected $buttons = [
'edit' 'edit'
]; ];
/**
* The table actions.
*
* @var array|string
*/
protected $actions = [ protected $actions = [
'delete' 'delete'
]; ];
/**
* The table options.
*
* @var array
*/
protected $options = [];
/**
* The table assets.
*
* @var array
*/
protected $assets = [];
} }

View File

@ -0,0 +1,28 @@
<?php namespace Visiosoft\AdvsModule\Status\Table;
use Anomaly\Streams\Platform\Entry\Contract\EntryInterface;
class StatusTableColumns
{
public function handle(StatusTableBuilder $builder)
{
$yes = trans('visiosoft.module.advs::field.yes.name');
$no = trans('visiosoft.module.advs::field.no.name');
$columns = [
'name',
'is_system' => [
'value' => function (EntryInterface $entry) use ($yes, $no) {
return $entry->is_system ? $yes : $no;
}
],
'user_access' => [
'value' => function (EntryInterface $entry) use ($yes, $no) {
return $entry->user_access ? $yes : $no;
}
],
];
$builder->setColumns($columns);
}
}

View File

@ -164,6 +164,29 @@ function dropdownRow(id, type) {
extend_ad + extend_ad +
"</a>\n"; "</a>\n";
if (Object.keys(userStatus).length) {
let statusItems = ''
for (const status in userStatus) {
statusItems += `
<li>
<a class="dropdown-item"
href="${statusChangeLink.replace(':adID', id).replace(':statusID', status)}">
${userStatus[status]}
</a>
</li>
`
}
dropdown += `
<li class="dropdown-submenu dropleft">
<button type="button" class="btn dropdown-item dropdown-toggle">Change Status</button>
<ul class="dropdown-menu">
${statusItems}
</ul>
</li>
`;
}
dropdown += "</div></div>"; dropdown += "</div></div>";
return dropdown; return dropdown;
@ -173,6 +196,21 @@ function addDropdownBlock() {
const dropdowns = $('.my-ads-dropdown') const dropdowns = $('.my-ads-dropdown')
for (let i = 0; i < dropdowns.length; i++) { for (let i = 0; i < dropdowns.length; i++) {
const currentDropdown = $(dropdowns[i]) const currentDropdown = $(dropdowns[i])
$('.dropdown-menu', currentDropdown).append(dropdownBlock.replace(':id', currentDropdown.data('id'))) $('> .dropdown-menu', currentDropdown).append(dropdownBlock.replace(':id', currentDropdown.data('id')))
} }
} }
// Nested dropdown
$('.tab-pane').on('click', '.dropdown-menu button.dropdown-toggle', function(e) {
if (!$(this).next().hasClass('show')) {
$(this).parents('.dropdown-menu').first().find('.show').removeClass('show');
}
var $subMenu = $(this).next('.dropdown-menu');
$subMenu.toggleClass('show');
$(this).parents('.my-ads-dropdown.show').on('hidden.bs.dropdown', function(e) {
$('.dropdown-submenu .show').removeClass('show');
});
return false;
});

View File

@ -74,6 +74,8 @@
var edit_ad = "{{ trans('visiosoft.module.profile::button.edit') }}"; var edit_ad = "{{ trans('visiosoft.module.profile::button.edit') }}";
var ads_per_page = "{{ setting_value('streams::per_page') }}"; var ads_per_page = "{{ setting_value('streams::per_page') }}";
var no_ads_message = "{{ trans('visiosoft.module.advs::field.no_ads') }}"; var no_ads_message = "{{ trans('visiosoft.module.advs::field.no_ads') }}";
let userStatus = JSON.parse(`{{ userStatus|raw }}`)
let statusChangeLink = `{{ changeStatusUrl }}`
let dropdownBlock = `{{ addBlock('profile/dropdown-ad', {'id': ':id'})|raw }}` let dropdownBlock = `{{ addBlock('profile/dropdown-ad', {'id': ':id'})|raw }}`
</script> </script>
{{ asset_add('scripts.js','visiosoft.module.profile::assets/js/ads.js') }} {{ asset_add('scripts.js','visiosoft.module.profile::assets/js/ads.js') }}

View File

@ -9,6 +9,7 @@ use Illuminate\Support\Facades\Auth;
use Rinvex\Subscriptions\Models\Plan; use Rinvex\Subscriptions\Models\Plan;
use Visiosoft\AdvsModule\Adv\AdvModel; use Visiosoft\AdvsModule\Adv\AdvModel;
use Visiosoft\AdvsModule\Adv\Event\ChangeStatusAd; use Visiosoft\AdvsModule\Adv\Event\ChangeStatusAd;
use Visiosoft\AdvsModule\Status\Contract\StatusRepositoryInterface;
use Visiosoft\LocationModule\Country\CountryModel; use Visiosoft\LocationModule\Country\CountryModel;
use Visiosoft\AlgoliaModule\Search\SearchModel; use Visiosoft\AlgoliaModule\Search\SearchModel;
use Visiosoft\CloudsiteModule\CloudsiteModule; use Visiosoft\CloudsiteModule\CloudsiteModule;
@ -222,9 +223,14 @@ class MyProfileController extends PublicController
} }
public function myAds() public function myAds(StatusRepositoryInterface $statusRepository)
{ {
return $this->view->make('visiosoft.module.profile::profile/ads'); $userStatus = $statusRepository->getUserAccessibleStatuses()->pluck('name', 'id')->toJson();
$changeStatusUrl = route('visiosoft.module.advs::ad.change.status', [':adID', ':statusID']);
return $this->view->make(
'visiosoft.module.profile::profile/ads',
compact('userStatus', 'changeStatusUrl')
);
} }
public function updateAjaxProfile(UserRepositoryInterface $user) public function updateAjaxProfile(UserRepositoryInterface $user)

View File

@ -26,42 +26,10 @@ use Visiosoft\ProfileModule\Profile\User\UserFormBuilder;
class ProfileModuleServiceProvider extends AddonServiceProvider class ProfileModuleServiceProvider extends AddonServiceProvider
{ {
/**
* Additional addon plugins.
*
* @type array|null
*/
protected $plugins = [ protected $plugins = [
ProfileModulePlugin::class ProfileModulePlugin::class
]; ];
/**
* The addon Artisan commands.
*
* @type array|null
*/
protected $commands = [];
/**
* The addon's scheduled commands.
*
* @type array|null
*/
protected $schedules = [];
/**
* The addon API routes.
*
* @type array|null
*/
protected $api = [];
/**
* The addon routes.
*
* @type array|null
*/
protected $routes = [ protected $routes = [
// Admin AdressController // Admin AdressController
'admin/profile' => 'Visiosoft\ProfileModule\Http\Controller\Admin\AdressController@index', 'admin/profile' => 'Visiosoft\ProfileModule\Http\Controller\Admin\AdressController@index',
@ -147,58 +115,10 @@ class ProfileModuleServiceProvider extends AddonServiceProvider
'ajax/get-user-info' => 'Visiosoft\ProfileModule\Http\Controller\CacheController@getUserInfo', 'ajax/get-user-info' => 'Visiosoft\ProfileModule\Http\Controller\CacheController@getUserInfo',
]; ];
/**
* The addon middleware.
*
* @type array|null
*/
protected $middleware = [
//Visiosoft\ProfileModule\Http\Middleware\ExampleMiddleware::class
];
/**
* Addon group middleware.
*
* @var array
*/
protected $groupMiddleware = [
//'web' => [
// Visiosoft\ProfileModule\Http\Middleware\ExampleMiddleware::class,
//],
];
/**
* Addon route middleware.
*
* @type array|null
*/
protected $routeMiddleware = [];
/**
* The addon event listeners.
*
* @type array|null
*/
protected $listeners = [
//Visiosoft\ProfileModule\Event\ExampleEvent::class => [
// Visiosoft\ProfileModule\Listener\ExampleListener::class,
//],
];
/**
* The addon alias bindings.
*
* @type array|null
*/
protected $aliases = [ protected $aliases = [
'Excel' => Excel::class, 'Excel' => Excel::class,
]; ];
/**
* The addon class bindings.
*
* @type array|null
*/
protected $bindings = [ protected $bindings = [
'updatePassword' => PasswordFormBuilder::class, 'updatePassword' => PasswordFormBuilder::class,
'userProfile' => UserFormBuilder::class, 'userProfile' => UserFormBuilder::class,
@ -210,11 +130,6 @@ class ProfileModuleServiceProvider extends AddonServiceProvider
ProfileEducationEntryModel::class => EducationModel::class, ProfileEducationEntryModel::class => EducationModel::class,
]; ];
/**
* The addon singleton bindings.
*
* @type array|null
*/
protected $singletons = [ protected $singletons = [
AdressRepositoryInterface::class => AdressRepository::class, AdressRepositoryInterface::class => AdressRepository::class,
EducationRepositoryInterface::class => EducationRepository::class, EducationRepositoryInterface::class => EducationRepository::class,
@ -223,47 +138,10 @@ class ProfileModuleServiceProvider extends AddonServiceProvider
'forgot_pass' => ForgotPassFormBuilder::class, 'forgot_pass' => ForgotPassFormBuilder::class,
]; ];
/**
* Additional service providers.
*
* @type array|null
*/
protected $providers = [ protected $providers = [
ExcelServiceProvider::class, ExcelServiceProvider::class,
]; ];
/**
* The addon view overrides.
*
* @type array|null
*/
protected $overrides = [
//'streams::errors/404' => 'module::errors/404',
//'streams::errors/500' => 'module::errors/500',
];
/**
* The addon mobile-only view overrides.
*
* @type array|null
*/
protected $mobile = [
//'streams::errors/404' => 'module::mobile/errors/404',
//'streams::errors/500' => 'module::mobile/errors/500',
];
/**
* Register the addon.
*/
public function register()
{
// Run extra pre-boot registration logic here.
// Use method injection or commands to bring in services.
}
/**
* Boot the addon.
*/
public function boot(AddonCollection $addonCollection) public function boot(AddonCollection $addonCollection)
{ {
$slug = 'export'; $slug = 'export';
@ -273,16 +151,4 @@ class ProfileModuleServiceProvider extends AddonServiceProvider
]; ];
$addonCollection->get('anomaly.module.users')->addSection($slug, $section); $addonCollection->get('anomaly.module.users')->addSection($slug, $section);
} }
/**
* Map additional addon routes.
*
* @param Router $router
*/
public function map(Router $router)
{
// Register dynamic routes here for example.
// Use method injection or commands to bring in services.
}
} }