mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Save Client / Contacts (#2523)
* View composers * Saving client and contacts * saving client and contacts * update client job * unique emails
This commit is contained in:
parent
cdb98ce528
commit
348890e8fa
@ -4,14 +4,19 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Client\EditClientRequest;
|
||||
use App\Http\Requests\Client\UpdateClientRequest;
|
||||
use App\Jobs\Client\UpdateClient;
|
||||
use App\Models\Client;
|
||||
use App\Repositories\ClientRepository;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\UserSessionAttributes;
|
||||
use Illuminate\Http\Request;
|
||||
use Yajra\DataTables\Facades\DataTables;
|
||||
use Yajra\DataTables\Html\Builder;
|
||||
|
||||
class ClientController extends Controller
|
||||
{
|
||||
use UserSessionAttributes;
|
||||
use MakesHash;
|
||||
|
||||
protected $clientRepo;
|
||||
|
||||
@ -81,7 +86,6 @@ class ClientController extends Controller
|
||||
'data' => 'function(d) { d.key = "value"; }',
|
||||
]);
|
||||
|
||||
//$data['header'] = $this->headerData();
|
||||
$data['html'] = $html;
|
||||
|
||||
return view('client.list', $data);
|
||||
@ -132,8 +136,8 @@ class ClientController extends Controller
|
||||
{
|
||||
|
||||
$data = [
|
||||
'header' => $this->headerData(),
|
||||
'client' => $client,
|
||||
'hashed_id' => $this->encodePrimarykey($client->id)
|
||||
];
|
||||
|
||||
return view('client.edit', $data);
|
||||
@ -143,13 +147,12 @@ class ClientController extends Controller
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @param App\Models\Client $client
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(UpdateClientRequest $request, Client $client)
|
||||
{
|
||||
|
||||
$client = $this->clientRepo->save($request, $client);
|
||||
$client = UpdateClient::dispatchNow($request, $client);
|
||||
$client->load('contacts', 'primary_contact');
|
||||
|
||||
return response()->json($client, 200);
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Utils\Traits\MakesHeaderData;
|
||||
use App\Utils\Traits\UserSessionAttributes;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
@ -11,5 +10,5 @@ use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests, MakesHeaderData;
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
}
|
||||
|
@ -25,9 +25,7 @@ class DashboardController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$data['header'] = $this->headerData();
|
||||
|
||||
return view('dashboard.index', $data);
|
||||
return view('dashboard.index');
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@ class UpdateClientRequest extends Request
|
||||
{
|
||||
return [
|
||||
'name' => 'required',
|
||||
'contacts.*.email' => 'email|unique:client_contacts,id'
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,9 @@ class HeaderComposer
|
||||
|
||||
private function headerData()
|
||||
{
|
||||
if(!auth()->user())
|
||||
return [];
|
||||
|
||||
//companies
|
||||
$companies = auth()->user()->companies;
|
||||
|
||||
|
41
app/Jobs/Client/UpdateClient.php
Normal file
41
app/Jobs/Client/UpdateClient.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Client;
|
||||
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Repositories\ClientRepository;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UpdateClient
|
||||
{
|
||||
use Dispatchable;
|
||||
|
||||
protected $request;
|
||||
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function __construct(Request $request, Client $client)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(ClientRepository $clientRepo)
|
||||
{
|
||||
return $clientRepo->save($this->request, $this->client);
|
||||
}
|
||||
}
|
@ -18,13 +18,13 @@ class Client extends BaseModel
|
||||
//protected $appends = ['client_id'];
|
||||
|
||||
protected $guarded = [
|
||||
'id'
|
||||
'id',
|
||||
'updated_at',
|
||||
'created_at',
|
||||
'deleted_at',
|
||||
];
|
||||
|
||||
public function getRouteKeyName()
|
||||
{
|
||||
return 'client_id';
|
||||
}
|
||||
|
||||
//protected $dates = ['deleted_at'];
|
||||
|
||||
public function getHashedIdAttribute()
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ namespace App\Models;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Hashids\Hashids;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laracasts\Presenter\PresentableTrait;
|
||||
@ -15,6 +16,7 @@ class ClientContact extends Authenticatable
|
||||
use Notifiable;
|
||||
use MakesHash;
|
||||
use PresentableTrait;
|
||||
use SoftDeletes;
|
||||
|
||||
// protected $appends = ['contact_id'];
|
||||
|
||||
@ -22,6 +24,8 @@ class ClientContact extends Authenticatable
|
||||
|
||||
protected $presenter = 'App\Models\Presenters\ClientContactPresenter';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
protected $guarded = [
|
||||
'id',
|
||||
];
|
||||
|
@ -14,14 +14,7 @@ class ComposerServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
View::composer(
|
||||
[
|
||||
'client.edit',
|
||||
'client.list',
|
||||
'dashboard.index',
|
||||
],
|
||||
'App\Http\ViewComposers\HeaderComposer'
|
||||
);
|
||||
View::composer('*', 'App\Http\ViewComposers\HeaderComposer');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,15 +2,53 @@
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\ClientContact;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class ClientContactRepository extends BaseRepository
|
||||
{
|
||||
|
||||
public function save($data)
|
||||
public function save(array $contacts, Client $client) : void
|
||||
{
|
||||
|
||||
/* Convert array to collection */
|
||||
$contacts = collect($contacts);
|
||||
|
||||
/* Get array of IDs which have been removed from the contacts array and soft delete each contact */
|
||||
collect($client->contacts->pluck('id'))->diffKeys($contacts->pluck('id'))->each(function($contact){
|
||||
ClientContact::destroy($contact);
|
||||
});
|
||||
|
||||
/* Set first record to primary - always*/
|
||||
$contacts = $contacts->sortBy('is_primary');
|
||||
|
||||
$contacts->first(function($contact){
|
||||
$contact['is_primary'] = true;
|
||||
});
|
||||
|
||||
//loop and update/create contacts
|
||||
$contacts->each(function ($contact) use ($client){
|
||||
|
||||
$update_contact = ClientContact::firstOrNew(
|
||||
['id' => $contact['id']],
|
||||
[
|
||||
'client_id' => $client->id,
|
||||
'company_id' => $client->company_id
|
||||
]
|
||||
);
|
||||
|
||||
$update_contact->fill($contact);
|
||||
$update_contact->save();
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -2,24 +2,32 @@
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Repositories\ClientContactRepository;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class ClientRepository extends BaseRepository
|
||||
{
|
||||
protected $clientContactRepository;
|
||||
protected $clientContactRepo;
|
||||
|
||||
public function __construct(ClientContactRepository $clientContactRepository)
|
||||
public function __construct(ClientContactRepository $clientContactRepo)
|
||||
{
|
||||
$this->clientContactRepository = $clientContactRepository;
|
||||
$this->clientContactRepo = $clientContactRepo;
|
||||
}
|
||||
|
||||
public function save($data)
|
||||
public function save(Request $request, Client $client) : ?Client
|
||||
{
|
||||
$client->fill($request->all())->save();
|
||||
Log::error(print_r($request->input(),1));
|
||||
$client->fill($request->input());
|
||||
$client->save();
|
||||
|
||||
$this->clientContactRepo->save($request->input('contacts'), $client);
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
}
|
16916
public/css/ninja.css
vendored
16916
public/css/ninja.css
vendored
File diff suppressed because one or more lines are too long
16916
public/css/ninja.min.css
vendored
16916
public/css/ninja.min.css
vendored
File diff suppressed because one or more lines are too long
13214
public/js/client_edit.js
vendored
13214
public/js/client_edit.js
vendored
File diff suppressed because one or more lines are too long
808
public/js/ninja.js
vendored
808
public/js/ninja.js
vendored
File diff suppressed because one or more lines are too long
808
public/js/ninja.min.js
vendored
808
public/js/ninja.min.js
vendored
File diff suppressed because one or more lines are too long
@ -4,7 +4,8 @@ import axios, { AxiosRequestConfig, AxiosPromise } from 'axios';
|
||||
|
||||
var VueApp: any = Vue;
|
||||
|
||||
declare var clientObject: any;
|
||||
declare var client_object: any;
|
||||
declare var hashed_id: string;
|
||||
|
||||
var App = new VueApp({
|
||||
el : '#client_edit',
|
||||
@ -16,7 +17,7 @@ var App = new VueApp({
|
||||
},
|
||||
mounted(this: any) {
|
||||
//this.client = {!! $client !!};
|
||||
this.client = clientObject;
|
||||
this.client = client_object;
|
||||
console.dir(this.client);
|
||||
},
|
||||
beforeMount: function () {
|
||||
@ -35,7 +36,7 @@ var App = new VueApp({
|
||||
},
|
||||
add(this: any){
|
||||
console.dir('i will add a contact here')
|
||||
this.client.contacts.push({first_name: '', last_name: '', email: '', phone: ''});
|
||||
this.client.contacts.push({first_name: '', last_name: '', email: '', phone: '', id: -1});
|
||||
window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
|
||||
this.$nextTick(() => {
|
||||
let index = this.client.contacts.length - 1;
|
||||
@ -46,7 +47,7 @@ var App = new VueApp({
|
||||
submit(this: any) {
|
||||
this.errors = {};
|
||||
|
||||
axios.put('/clients/', this.client).then(response => {
|
||||
axios.put('/clients/' + hashed_id, this.client).then(response => {
|
||||
// axios.put('/clients/' + {{ $client->present()->id }}, this.client).then(response => {
|
||||
this.client = response.data;
|
||||
}).catch(error => {
|
||||
|
@ -46,12 +46,13 @@
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
</main>
|
||||
<script>
|
||||
var clientObject = {!! $client !!};
|
||||
var client_object = {!! $client !!};
|
||||
var hashed_id = '{{ $hashed_id }}';
|
||||
</script>
|
||||
|
||||
<script src=" {{ mix('/js/client_edit.js') }}"></script>
|
||||
|
||||
</main>
|
||||
|
||||
@endsection
|
@ -1,5 +1,3 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
|
||||
|
||||
<h1>Contact homepage</h1>
|
Loading…
x
Reference in New Issue
Block a user