Link Customer creation to a Mailbox

This only covers Customer creation going through the dedicated form.
This commit is contained in:
Antoine Le Gonidec 2024-07-05 14:18:54 +02:00
parent 2ac4519d9a
commit b754fefe70
Signed by: vv221
GPG key ID: 636B78F91CEB80D8
6 changed files with 346 additions and 6 deletions

View file

@ -0,0 +1,12 @@
@extends('layouts.app')
@section('title', 'Add Customer (MMF)')
@section('content')
@include('freescout-restricted-customers::customers/partials/edit_form', ['save_button_title' => __('Add')])
@endsection
@section('javascript')
@parent
multiInputInit();
@endsection

View file

@ -0,0 +1,301 @@
@include('partials/flash_messages')
@action('customer.edit.before_form', $customer)
<div class="container form-container">
<div class="row">
<div class="col-xs-12">
<form class="form-horizontal margin-top" method="POST" action="" enctype="multipart/form-data">
{{ csrf_field() }}
<!-- Mandatory field: Mailbox this Customer instance is linked to -->
<div class="form-group{{ $errors->has('mailbox') ? ' has-error' : '' }} margin-bottom-0">
<label for="mailbox" class="col-sm-2 control-label">{{ __('Mailbox') }}</label>
<div class="col-sm-6">
<div class="multi-container">
<div class="multi-item">
<div>
<div class="input-group input-group-flex input-sized-lg">
<select class="form-control" name="mailbox" required>
<!-- TODO: Automatically select the Mailbox currently set, if there is one. -->
<option value="" disabled selected>---</option>
@foreach($mailboxes as $mailbox)
<option value="{{ $mailbox->id }}">{{ $mailbox->name }}</option>
@endforeach
</select>
</div>
</div>
</div>
<p class="block-help"><a href="#" class="multi-add" tabindex="-1">{{ __('Add a mailbox') }}</a></p>
</div>
@include('partials/field_error', ['field'=>'mailbox'])
</div>
</div>
<div class="form-group{{ $errors->has('first_name') ? ' has-error' : '' }}">
<label for="first_name" class="col-sm-2 control-label">{{ __('First Name') }}</label>
<div class="col-sm-6">
<input id="first_name" type="text" class="form-control input-sized-lg" name="first_name" value="{{ old('first_name', $customer->first_name) }}" maxlength="255">
@include('partials/field_error', ['field'=>'first_name'])
</div>
</div>
<div class="form-group{{ $errors->has('last_name') ? ' has-error' : '' }}">
<label for="last_name" class="col-sm-2 control-label">{{ __('Last Name') }}</label>
<div class="col-sm-6">
<input id="last_name" type="text" class="form-control input-sized-lg" name="last_name" value="{{ old('last_name', $customer->last_name) }}" maxlength="255">
@include('partials/field_error', ['field'=>'last_name'])
</div>
</div>
<div class="form-group margin-bottom-0">
<label for="emails" class="col-sm-2 control-label">{{ __('Email') }}</label>
<div class="col-sm-6">
<div class="multi-container">
@foreach (old('emails', $emails) as $i => $email)
<div class="multi-item {{ $errors->has('emails.'.$i) ? ' has-error' : '' }}">
<div>
<input type="email" class="form-control input-sized-lg" name="emails[]" value="{{ $email }}" maxlength="191">
<a href="#" class="multi-remove" tabindex="-1"><i class="glyphicon glyphicon-remove"></i></a>
</div>
@include('partials/field_error', ['field'=>'emails.'.$i])
</div>
@endforeach
<p class="block-help"><a href="#" class="multi-add " tabindex="-1">{{ __('Add an email address') }}</a></p>
</div>
{{-- @include('partials/field_error', ['field'=>'emails.*']) --}}
</div>
</div>
<div class="form-group{{ $errors->has('phones') ? ' has-error' : '' }} margin-bottom-0">
<label for="phones" class="col-sm-2 control-label">{{ __('Phone') }}</label>
<div class="col-sm-6">
<div class="multi-container">
@foreach ($customer->getPhones(true) as $i => $phone)
@if (!empty($phone['type']) && isset($phone['value']))
<div class="multi-item">
<div>
<div class="input-group input-group-flex input-sized-lg">
<select class="form-control" name="phones[{{ $i }}][type]">
@foreach(\App\Customer::$phone_types as $phone_type => $name)
<option value="{{$phone_type}}" {{ $phone_type == $phone['type'] ? 'selected="selected' : '' }}>{{ \App\Customer::getPhoneTypeName($phone_type) }}</option>
@endforeach
</select>
<input type="tel" class="form-control " name="phones[{{ $i }}][value]" value="{{ $phone['value'] }}">
</div>
<a href="#" class="multi-remove" tabindex="-1"><i class="glyphicon glyphicon-remove"></i></a>
</div>
</div>
@endif
@endforeach
<p class="block-help" data-max-i="{{ $i }}"><a href="#" class="multi-add" tabindex="-1">{{ __('Add a phone number') }}</a></p>
</div>
@include('partials/field_error', ['field'=>'phones'])
</div>
</div>
<div class="form-group{{ $errors->has('company') ? ' has-error' : '' }}">
<label for="company" class="col-sm-2 control-label">{{ __('Company') }}</label>
<div class="col-sm-6">
<input id="company" type="text" class="form-control input-sized-lg" name="company" value="{{ old('company', $customer->company) }}" placeholder="{{ __('(optional)') }}" maxlength="255">
@include('partials/field_error', ['field'=>'company'])
</div>
</div>
<div class="form-group{{ $errors->has('job_title') ? ' has-error' : '' }}">
<label for="job_title" class="col-sm-2 control-label">{{ __('Job Title') }}</label>
<div class="col-sm-6">
<input id="job_title" type="text" class="form-control input-sized-lg" name="job_title" value="{{ old('job_title', $customer->job_title) }}" placeholder="{{ __('(optional)') }}" maxlength="100">
@include('partials/field_error', ['field'=>'job_title'])
</div>
</div>
<div class="form-group{{ $errors->has('websites') ? ' has-error' : '' }} margin-bottom-0">
<label for="websites" class="col-sm-2 control-label">{{ __('Website') }}</label>
<div class="col-sm-6">
<div class="multi-container">
@foreach ($customer->getWebsites(true) as $website)
<div class="multi-item">
<div>
<input type="url" class="form-control input-sized-lg" name="websites[]" value="{{ $website }}" maxlength="100">
<a href="#" class="multi-remove" tabindex="-1"><i class="glyphicon glyphicon-remove"></i></a>
</div>
</div>
@endforeach
<p class="block-help"><a href="#" class="multi-add" tabindex="-1">{{ __('Add a website') }}</a></p>
</div>
@include('partials/field_error', ['field'=>'websites'])
</div>
</div>
<div class="form-group{{ $errors->has('social') ? ' has-error' : '' }} margin-bottom-0">
<label for="social_profiles" class="col-sm-2 control-label">{{ __('Social Profiles') }}</label>
<div class="col-sm-6">
<div class="multi-container">
@foreach ($customer->getSocialProfiles(true) as $i => $social_profile)
@if (isset($social_profile['type']) && isset($social_profile['value']))
<div class="multi-item">
<div>
<div class="input-group input-group-flex input-sized-lg">
<select class="form-control" name="social_profiles[{{ $i }}][type]">
<option value=""></option>
@foreach (App\Customer::$social_types as $social_type_id => $social_type_code)
<option value="{{ $social_type_id }}" @if ((int)$social_profile['type'] == $social_type_id) selected @endif>{{ __(App\Customer::$social_type_names[$social_type_id]) }}</option>
@endforeach
</select>
<span class="input-group-btn" style="width:0px;"></span>
<input type="text" class="form-control" name="social_profiles[{{ $i }}][value]" value="{{ $social_profile['value'] }}">
</div>
<a href="#" class="multi-remove" tabindex="-1"><i class="glyphicon glyphicon-remove"></i></a>
</div>
</div>
@endif
@endforeach
<p class="block-help" data-max-i="{{ $i }}"><a href="#" class="multi-add" tabindex="-1">{{ __('Add a social profile') }}</a></p>
</div>
@include('partials/field_error', ['field'=>'social_profiles'])
</div>
</div>
{{--
<div class="form-group{{ $errors->has('age') ? ' has-error' : '' }}">
<label for="age" class="col-sm-2 control-label">{{ __('Age') }}</label>
<div class="col-sm-6">
<input id="age" type="text" class="form-control input-sized-lg" name="age" value="{{ old('age', $customer->age) }}" placeholder="{{ __('(optional)') }}" maxlength="7">
@include('partials/field_error', ['field'=>'age'])
</div>
</div>
<div class="form-group{{ $errors->has('gender') ? ' has-error' : '' }}">
<label for="gender" class="col-sm-2 control-label">{{ __('Gender') }}</label>
<div class="col-sm-6">
<select class="form-control input-sized-lg" name="gender">
<option value=""></option>
<option value="{{ App\Customer::GENDER_MALE }}" @if (old('gender', $customer->gender) == App\Customer::GENDER_MALE ) selected @endif>{{ __('Male') }}</option>
<option value="{{ App\Customer::GENDER_FEMALE }}" @if (old('gender', $customer->gender) == App\Customer::GENDER_FEMALE ) selected @endif>{{ __('Female') }}</option>
</select>
@include('partials/field_error', ['field'=>'gender'])
</div>
</div>
--}}
<div class="form-group{{ $errors->has('gender') ? ' has-error' : '' }}">
<label for="country" class="col-sm-2 control-label">{{ __('Country') }}</label>
<div class="col-sm-6">
<select class="form-control input-sized-lg" name="country">
<option value=""></option>
@foreach (App\Customer::$countries as $country_code => $country_name)
<option value="{{ $country_code }}" @if (old('country', $customer->country) == $country_code) selected @endif>{{ __($country_name) }}</option>
@endforeach
</select>
<div class="block-help small margin-bottom-0">
<a href="#address-collapse" data-toggle="collapse">{{ __('Address') }} <span class="caret"></span></a>
</div>
@include('partials/field_error', ['field'=>'country'])
</div>
</div>
<div id="address-collapse" @if (empty(old('state', $customer->state)) && empty(old('city', $customer->city)) && empty(old('address', $customer->address)) && empty(old('zip', $customer->zip)))@else class="collapse in" @endif>
<div class="form-group{{ $errors->has('state') ? ' has-error' : '' }}">
<label for="state" class="col-sm-2 control-label">{{ __('State') }}</label>
<div class="col-sm-6">
<input id="state" type="text" class="form-control input-sized-lg" name="state" value="{{ old('state', $customer->state) }}" placeholder="{{ __('(optional)') }}" maxlength="255">
@include('partials/field_error', ['field'=>'state'])
</div>
</div>
<div class="form-group{{ $errors->has('city') ? ' has-error' : '' }}">
<label for="city" class="col-sm-2 control-label">{{ __('City') }}</label>
<div class="col-sm-6">
<input id="city" type="text" class="form-control input-sized-lg" name="city" value="{{ old('city', $customer->city) }}" placeholder="{{ __('(optional)') }}" maxlength="255">
@include('partials/field_error', ['field'=>'city'])
</div>
</div>
<div class="form-group{{ $errors->has('address') ? ' has-error' : '' }}">
<label for="address" class="col-sm-2 control-label">{{ __('Address') }}</label>
<div class="col-sm-6">
<input id="address" type="text" class="form-control input-sized-lg" name="address" value="{{ old('address', $customer->address) }}" placeholder="{{ __('(optional)') }}" maxlength="255">
@include('partials/field_error', ['field'=>'address'])
</div>
</div>
<div class="form-group{{ $errors->has('zip') ? ' has-error' : '' }}">
<label for="zip" class="col-sm-2 control-label">{{ __('ZIP') }}</label>
<div class="col-sm-6">
<input id="zip" type="text" class="form-control input-sized-lg" name="zip" value="{{ old('zip', $customer->zip) }}" placeholder="{{ __('(optional)') }}" maxlength="12">
@include('partials/field_error', ['field'=>'zip'])
</div>
</div>
</div>
<div class="form-group{{ $errors->has('photo_url') ? ' has-error' : '' }} margin-bottom-0">
<label for="photo_url" class="col-sm-2 control-label">{{ __('Photo') }}</label>
<div class="col-sm-6">
<input type="file" name="photo_url">
<p class="block-help">(JPG, GIF, PNG)</p>
@include('partials/field_error', ['field'=>'photo_url'])
</div>
</div>
<div class="form-group{{ $errors->has('notes') ? ' has-error' : '' }}">
<label for="notes" class="col-sm-2 control-label">{{ __('Notes') }}</label>
<div class="col-sm-6">
<textarea id="notes" class="form-control input-sized-lg" name="notes" rows="2">{{ old('notes', $customer->notes) }}</textarea>
@include('partials/field_error', ['field'=>'notes'])
</div>
</div>
@action('customer.edit.after_fields', $customer, $errors)
<div class="form-group">
<div class="col-sm-6 col-sm-offset-2">
<button type="submit" class="btn btn-primary">
@if (!empty($save_button_title))
{{ $save_button_title }}
@else
{{ __('Save Profile') }}
@endif
</button>
</div>
</div>
</form>
</div>
</div>
</div>

View file

@ -18,6 +18,8 @@ Route::get('/customers/ajax-search', ['uses' => CustomersController::class . '@a
Route::post('/customers/ajax', ['uses' => CustomersController::class . '@ajax', 'laroute' => true])->name('customers.ajax'); Route::post('/customers/ajax', ['uses' => CustomersController::class . '@ajax', 'laroute' => true])->name('customers.ajax');
Route::group([ 'roles' => ['user', 'admin'] ], function() { Route::group([ 'roles' => ['user', 'admin'] ], function() {
Route::get('/customers/new', CrmController::class . '@createCustomer')->name('freescout-restricted-customers.create_customer');
// The Crm module initialization will crash if no route named "crm.create_customer" is set.
Route::get('/customers/new', CrmController::class . '@createCustomer')->name('crm.create_customer'); Route::get('/customers/new', CrmController::class . '@createCustomer')->name('crm.create_customer');
Route::post('/customers/new', CrmController::class . '@createCustomerSave'); Route::post('/customers/new', CrmController::class . '@createCustomerSave');
Route::get('/crm/ajax-html/{action}/{param?}', ['uses' => CrmController::class . '@ajaxHtml'])->name('crm.ajax_html'); Route::get('/crm/ajax-html/{action}/{param?}', ['uses' => CrmController::class . '@ajaxHtml'])->name('crm.ajax_html');

View file

@ -6,6 +6,12 @@
namespace MMF\FreescoutRestrictedCustomers; namespace MMF\FreescoutRestrictedCustomers;
use App\Email;
use App\CustomerChannel;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
use Watson\Rememberable\Rememberable;
use MMF\FreescoutRestrictedCustomers\Mailbox; use MMF\FreescoutRestrictedCustomers\Mailbox;
use App\Customer as BaseCustomer; use App\Customer as BaseCustomer;
@ -43,4 +49,19 @@ class Customer extends BaseCustomer {
public function mailbox() { public function mailbox() {
return $this->belongsTo(Mailbox::class); return $this->belongsTo(Mailbox::class);
} }
/**
* Set empty fields.
*/
public function setData($data, $replace_data = true, $save = false) {
// Set the Mailbox this Customer should be linked to.
// TODO: Throw an error if the Mailbox is not set.
if ( isset($data['mailbox']) ) {
// TODO: Check that the current user is allowed to access this Mailbox.
$data['mailbox_id'] = $data['mailbox'];
unset($data['mailbox']);
}
return parent::setData($data, $replace_data, $save);
}
} }

View file

@ -17,6 +17,7 @@ class FreescoutRestrictedCustomersServiceProvider extends ServiceProvider {
public function boot() { public function boot() {
$this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); $this->loadMigrationsFrom(__DIR__ . '/../database/migrations');
$this->registerRoutes(); $this->registerRoutes();
$this->loadViewsFrom(__DIR__.'/../resources/views', 'freescout-restricted-customers');
} }
protected function registerRoutes() { protected function registerRoutes() {

View file

@ -19,13 +19,16 @@ use MMF\FreescoutRestrictedCustomers\Customer;
class CrmController extends BaseCrmController { class CrmController extends BaseCrmController {
public function createCustomer(Request $request) { public function createCustomer(Request $request) {
// TODO: Find a way to call parent::createCustomer while only overriding the Customer class,
// instead of overriding the whole method here.
$customer = new Customer(); $customer = new Customer();
return view('crm::create_customer', [ // Get the list of Mailboxes the current User has access to.
$user = auth()->user();
$mailboxes = $user->mailboxesCanView();
return view('freescout-restricted-customers::create_customer', [
'customer' => $customer, 'customer' => $customer,
'emails' => [''] 'mailboxes' => $mailboxes,
'emails' => [''],
]); ]);
} }
@ -63,7 +66,7 @@ class CrmController extends BaseCrmController {
} }
if ($fail || $validator->fails()) { if ($fail || $validator->fails()) {
return redirect()->route('crm.create_customer') return redirect()->route('freescout-restricted-customers.create_customer')
->withErrors($validator) ->withErrors($validator)
->withInput(); ->withInput();
} }