diff --git a/app/Http/Controllers/ClientController.php b/app/Http/Controllers/ClientController.php index 1e869d8756d6..51f2b4b1a01b 100644 --- a/app/Http/Controllers/ClientController.php +++ b/app/Http/Controllers/ClientController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Http\Requests\Client\EditClientRequest; +use App\Http\Requests\Client\StoreClientRequest; use App\Http\Requests\Client\UpdateClientRequest; use App\Jobs\Client\StoreClient; use App\Jobs\Client\UpdateClient; @@ -12,6 +13,7 @@ use App\Repositories\ClientRepository; use App\Utils\Traits\MakesHash; use App\Utils\Traits\UserSessionAttributes; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Log; use Yajra\DataTables\Facades\DataTables; use Yajra\DataTables\Html\Builder; @@ -101,8 +103,11 @@ class ClientController extends Controller public function create() { $client = new Client; + $client->name = ''; + $client->company_id = $this->getCurrentCompanyId(); $client_contact = new ClientContact; $client_contact->first_name = ""; + $client_contact->id = 0; $client->contacts->add($client_contact); @@ -120,16 +125,22 @@ class ClientController extends Controller * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ - public function store(Request $request) + public function store(StoreClientRequest $request) { $client = StoreClient::dispatchNow($request, new Client); + $client->load('contacts', 'primary_contact'); + $client->hashed_id = $this->encodePrimarykey($client->id); + +/* $data = [ 'client' => $client, 'hashed_id' => $this->encodePrimarykey($client->id) ]; +*/ + Log::error(print_r($client,1)); + return response()->json($client, 200); - return view('client.edit', $data); } /** diff --git a/app/Http/Requests/Client/StoreClientRequest.php b/app/Http/Requests/Client/StoreClientRequest.php index 8e48eb0601e7..bbb772c58f4e 100644 --- a/app/Http/Requests/Client/StoreClientRequest.php +++ b/app/Http/Requests/Client/StoreClientRequest.php @@ -19,12 +19,27 @@ class StoreClientRequest extends Request } public function rules() + { + /* Ensure we have a client name, and that all emails are unique*/ + $rules['name'] = 'required'; + $contacts = request('contacts'); + + for ($i = 0; $i < count($contacts); $i++) { + $rules['contacts.' . $i . '.email'] = 'required|email|unique:client_contacts,email,' . isset($contacts[$i]['id']); + } + + return $rules; + + + } + + public function messages() { return [ - 'name' => 'required', - 'contacts.*.email' => 'email|unique:client_contacts,email' - + 'unique' => trans('validation.unique', ['attribute' => 'email']), + //'required' => trans('validation.required', ['attribute' => 'email']), + 'contacts.*.email.required' => trans('validation.email', ['attribute' => 'email']), ]; } diff --git a/app/Http/Requests/Client/UpdateClientRequest.php b/app/Http/Requests/Client/UpdateClientRequest.php index 99bc902e633f..704953ed621a 100644 --- a/app/Http/Requests/Client/UpdateClientRequest.php +++ b/app/Http/Requests/Client/UpdateClientRequest.php @@ -22,8 +22,7 @@ class UpdateClientRequest extends Request public function rules() { - - /* Ensure we have a client name, and that all emails are unique!!!!!*/ + /* Ensure we have a client name, and that all emails are unique*/ $rules['name'] = 'required'; $contacts = request('contacts'); diff --git a/app/Models/ClientContact.php b/app/Models/ClientContact.php index b1f727d1cea0..98198eeb50b5 100644 --- a/app/Models/ClientContact.php +++ b/app/Models/ClientContact.php @@ -29,7 +29,7 @@ class ClientContact extends Authenticatable protected $guarded = [ 'id', ]; - + protected $hidden = [ 'password', 'remember_token', diff --git a/app/Repositories/ClientContactRepository.php b/app/Repositories/ClientContactRepository.php index 681c4fb4b351..0e8658337439 100644 --- a/app/Repositories/ClientContactRepository.php +++ b/app/Repositories/ClientContactRepository.php @@ -19,7 +19,7 @@ class ClientContactRepository extends BaseRepository $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){ + collect($client->contacts->pluck('id'))->diff($contacts->pluck('id'))->each(function($contact){ ClientContact::destroy($contact); }); diff --git a/public/js/client_create.js b/public/js/client_create.js index 21fc87fd7088..db47945e39fc 100644 --- a/public/js/client_create.js +++ b/public/js/client_create.js @@ -1631,6 +1631,104 @@ module.exports = { }; +/***/ }), + +/***/ "./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./node_modules/vue-toastr/src/vue-toastr.scss": +/***/ (function(module, exports, __webpack_require__) { + +exports = module.exports = __webpack_require__("./node_modules/css-loader/lib/css-base.js")(false); +// imports + + +// module +exports.push([module.i, ".toast-title {\n font-weight: bold; }\n\n.toast-message {\n -ms-word-wrap: break-word;\n word-wrap: break-word; }\n .toast-message a,\n .toast-message label {\n color: #FFFFFF; }\n .toast-message a:hover {\n color: #CCCCCC;\n text-decoration: none; }\n\n.toast-close-button {\n position: relative;\n right: -0.3em;\n top: -0.3em;\n float: right;\n font-size: 20px;\n font-weight: bold;\n color: #FFFFFF;\n -webkit-text-shadow: 0 1px 0 white;\n text-shadow: 0 1px 0 white;\n opacity: 0.8; }\n .toast-close-button:hover, .toast-close-button:focus {\n color: #000000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.4; }\n\n/*Additional properties for button version\n iOS requires the button element instead of an anchor tag.\n If you want the anchor version, it requires `href=\"#\"`.*/\nbutton.toast-close-button {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none; }\n\n.toast-top-center {\n top: 0;\n right: 0;\n width: 100%; }\n\n.toast-bottom-center {\n bottom: 0;\n right: 0;\n width: 100%; }\n\n.toast-top-full-width {\n top: 0;\n right: 0;\n width: 100%; }\n\n.toast-bottom-full-width {\n bottom: 0;\n right: 0;\n width: 100%; }\n\n.toast-top-left {\n top: 12px;\n left: 12px; }\n\n.toast-top-right {\n top: 12px;\n right: 12px; }\n\n.toast-bottom-right {\n right: 12px;\n bottom: 12px; }\n\n.toast-bottom-left {\n bottom: 12px;\n left: 12px; }\n\n.toast-container {\n position: fixed;\n z-index: 999999;\n pointer-events: none;\n /*overrides*/ }\n .toast-container * {\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n box-sizing: border-box; }\n .toast-container > div {\n position: relative;\n pointer-events: auto;\n overflow: hidden;\n margin: 0 0 6px;\n padding: 15px 15px 15px 50px;\n width: 300px;\n -moz-border-radius: 3px 3px 3px 3px;\n -webkit-border-radius: 3px 3px 3px 3px;\n border-radius: 3px 3px 3px 3px;\n background-position: 15px center;\n background-repeat: no-repeat;\n -moz-box-shadow: 0 0 12px #999999;\n -webkit-box-shadow: 0 0 12px #999999;\n box-shadow: 0 0 12px #999999;\n color: #FFFFFF;\n opacity: 0.8; }\n .toast-container > :hover {\n -moz-box-shadow: 0 0 12px #000000;\n -webkit-box-shadow: 0 0 12px #000000;\n box-shadow: 0 0 12px #000000;\n opacity: 1;\n cursor: pointer; }\n .toast-container > .toast-info {\n background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=\") !important; }\n .toast-container > .toast-error {\n background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=\") !important; }\n .toast-container > .toast-success {\n background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==\") !important; }\n .toast-container > .toast-warning {\n background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=\") !important; }\n .toast-container.toast-top-center > div,\n .toast-container.toast-bottom-center > div {\n width: 300px;\n margin-left: auto;\n margin-right: auto; }\n .toast-container.toast-top-full-width > div,\n .toast-container.toast-bottom-full-width > div {\n width: 96%;\n margin-left: auto;\n margin-right: auto; }\n\n.toast {\n background-color: #030303; }\n\n.toast-success {\n background-color: #51A351; }\n\n.toast-error {\n background-color: #BD362F; }\n\n.toast-info {\n background-color: #2F96B4; }\n\n.toast-warning {\n background-color: #F89406; }\n\n.toast-progress {\n position: absolute;\n left: 0;\n bottom: 0;\n height: 4px;\n background-color: #000000;\n opacity: 0.4; }\n\n/*Responsive Design*/\n@media all and (max-width: 240px) {\n .toast-container > div {\n padding: 8px 8px 8px 50px;\n width: 11em; }\n .toast-container .toast-close-button {\n right: -0.2em;\n top: -0.2em; } }\n\n@media all and (min-width: 241px) and (max-width: 480px) {\n .toast-container > div {\n padding: 8px 8px 8px 50px;\n width: 18em; }\n .toast-container .toast-close-button {\n right: -0.2em;\n top: -0.2em; } }\n\n@media all and (min-width: 481px) and (max-width: 768px) {\n .toast-container > div {\n padding: 15px 15px 15px 50px;\n width: 25em; } }\n", ""]); + +// exports + + +/***/ }), + +/***/ "./node_modules/css-loader/lib/css-base.js": +/***/ (function(module, exports) { + +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +// css base code, injected by the css-loader +module.exports = function(useSourceMap) { + var list = []; + + // return the list of modules as css string + list.toString = function toString() { + return this.map(function (item) { + var content = cssWithMappingToString(item, useSourceMap); + if(item[2]) { + return "@media " + item[2] + "{" + content + "}"; + } else { + return content; + } + }).join(""); + }; + + // import a list of modules into the list + list.i = function(modules, mediaQuery) { + if(typeof modules === "string") + modules = [[null, modules, ""]]; + var alreadyImportedModules = {}; + for(var i = 0; i < this.length; i++) { + var id = this[i][0]; + if(typeof id === "number") + alreadyImportedModules[id] = true; + } + for(i = 0; i < modules.length; i++) { + var item = modules[i]; + // skip already imported module + // this implementation is not 100% perfect for weird media query combinations + // when a module is imported multiple times with different media queries. + // I hope this will never occur (Hey this way we have smaller bundles) + if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) { + if(mediaQuery && !item[2]) { + item[2] = mediaQuery; + } else if(mediaQuery) { + item[2] = "(" + item[2] + ") and (" + mediaQuery + ")"; + } + list.push(item); + } + } + }; + return list; +}; + +function cssWithMappingToString(item, useSourceMap) { + var content = item[1] || ''; + var cssMapping = item[3]; + if (!cssMapping) { + return content; + } + + if (useSourceMap && typeof btoa === 'function') { + var sourceMapping = toComment(cssMapping); + var sourceURLs = cssMapping.sources.map(function (source) { + return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */' + }); + + return [content].concat(sourceURLs).concat([sourceMapping]).join('\n'); + } + + return [content].join('\n'); +} + +// Adapted from convert-source-map (MIT) +function toComment(sourceMap) { + // eslint-disable-next-line no-undef + var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))); + var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64; + + return '/*# ' + data + ' */'; +} + + /***/ }), /***/ "./node_modules/is-buffer/index.js": @@ -2044,6 +2142,462 @@ process.umask = function() { return 0; }; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__("./node_modules/webpack/buildin/global.js"), __webpack_require__("./node_modules/process/browser.js"))) +/***/ }), + +/***/ "./node_modules/style-loader/lib/addStyles.js": +/***/ (function(module, exports, __webpack_require__) { + +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +var stylesInDom = {}; + +var memoize = function (fn) { + var memo; + + return function () { + if (typeof memo === "undefined") memo = fn.apply(this, arguments); + return memo; + }; +}; + +var isOldIE = memoize(function () { + // Test for IE <= 9 as proposed by Browserhacks + // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805 + // Tests for existence of standard globals is to allow style-loader + // to operate correctly into non-standard environments + // @see https://github.com/webpack-contrib/style-loader/issues/177 + return window && document && document.all && !window.atob; +}); + +var getElement = (function (fn) { + var memo = {}; + + return function(selector) { + if (typeof memo[selector] === "undefined") { + memo[selector] = fn.call(this, selector); + } + + return memo[selector] + }; +})(function (target) { + return document.querySelector(target) +}); + +var singleton = null; +var singletonCounter = 0; +var stylesInsertedAtTop = []; + +var fixUrls = __webpack_require__("./node_modules/style-loader/lib/urls.js"); + +module.exports = function(list, options) { + if (typeof DEBUG !== "undefined" && DEBUG) { + if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment"); + } + + options = options || {}; + + options.attrs = typeof options.attrs === "object" ? options.attrs : {}; + + // Force single-tag solution on IE6-9, which has a hard limit on the # of + +
+{!! $key !!} | + @endforeach +|
---|---|
{!! $value !!} | + @else ++ @endif + @endforeach + |