Supplier.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <?php
  2. namespace App\Http\Livewire;
  3. use Livewire\Component;
  4. use Illuminate\Support\Facades\Auth;
  5. use Illuminate\Support\Facades\Log;
  6. use App\Http\Middleware\TenantMiddleware;
  7. class Supplier extends Component
  8. {
  9. public $records, $name, $fiscal_code, $vat, $address, $zip_code, $nation_id, $province_id, $city_id, $referent, $website, $phone, $email, $enabled, $dataId, $update = false, $add = false;
  10. public $referent_first_name, $referent_last_name, $referent_email, $referent_phone, $referent_mobile, $showReset = false;
  11. public $isItaly = true;
  12. public $searchTxt;
  13. public $search;
  14. public $showArchived = false;
  15. protected $rules = [
  16. 'name' => 'required',
  17. 'vat' => 'nullable|unique:suppliers,vat',
  18. 'fiscal_code' => 'nullable|unique:suppliers,fiscal_code'
  19. ];
  20. protected $messages = [
  21. 'name.required' => 'Il nome è obbligatorio',
  22. 'vat.unique' => 'Un fornitore con questa Partita IVA esiste già',
  23. 'fiscal_code.unique' => 'Un fornitore con questo Codice Fiscale esiste già'
  24. ];
  25. public function boot()
  26. {
  27. app(TenantMiddleware::class)->setupTenantConnection();
  28. }
  29. public function resetFields()
  30. {
  31. $this->name = '';
  32. $this->fiscal_code = '';
  33. $this->vat = '';
  34. $this->address = '';
  35. $this->zip_code = '';
  36. $this->nation_id = null;
  37. $this->province_id = null;
  38. $this->city_id = null;
  39. $this->referent = '';
  40. $this->website = '';
  41. $this->phone = '';
  42. $this->email = '';
  43. $this->enabled = true;
  44. $this->referent_first_name = '';
  45. $this->referent_last_name = '';
  46. $this->referent_email = '';
  47. $this->referent_phone = '';
  48. $this->referent_mobile = '';
  49. $this->emit('load-data-table');
  50. }
  51. public $sortField = 'name';
  52. public $sortAsc = true;
  53. public function sortBy($field)
  54. {
  55. if ($this->sortField === $field) {
  56. $this->sortAsc = ! $this->sortAsc;
  57. } else {
  58. $this->sortAsc = true;
  59. }
  60. $this->sortField = $field;
  61. }
  62. public function mount()
  63. {
  64. if (Auth::user()->level != env('LEVEL_ADMIN', 0))
  65. return redirect()->to('/dashboard');
  66. if (isset($_GET["new"]))
  67. $this->add();
  68. }
  69. public function search()
  70. {
  71. if ($this->searchTxt != '') {
  72. $this->search = $this->searchTxt;
  73. $this->showReset = true;
  74. }
  75. }
  76. public function resetSearch()
  77. {
  78. $this->showReset = false;
  79. $this->searchTxt = '';
  80. $this->search = $this->searchTxt;
  81. }
  82. public function render()
  83. {
  84. if ($this->showArchived) {
  85. // Show all suppliers including archived ones
  86. $this->records = \App\Models\Supplier::orderBy('name')->get();
  87. } else {
  88. // Show only non-archived suppliers
  89. $this->records = \App\Models\Supplier::where(function($query) {
  90. $query->where('archived', 0)->orWhereNull('archived');
  91. })->orderBy('name')->get();
  92. }
  93. return view('livewire.supplier');
  94. }
  95. public function hydrate()
  96. {
  97. $this->emit('load-select');
  98. }
  99. public function checkIsItaly()
  100. {
  101. $n = \App\Models\Nation::findOrFail($this->nation_id);
  102. $this->isItaly = $n->is_italy;
  103. }
  104. public function add()
  105. {
  106. $this->resetFields();
  107. $this->emit('load-select');
  108. $this->add = true;
  109. $this->update = false;
  110. }
  111. private function cleanEmptyFields()
  112. {
  113. $this->vat = trim($this->vat) === '' ? null : trim($this->vat);
  114. $this->fiscal_code = trim($this->fiscal_code) === '' ? null : trim($this->fiscal_code);
  115. }
  116. public function store()
  117. {
  118. $this->validate();
  119. $vatToCheck = trim($this->vat);
  120. $existingSupplier = \App\Models\Supplier::where('vat', $vatToCheck)->first();
  121. Log::info('VAT validation detailed debug', [
  122. 'vat_input' => $this->vat,
  123. 'vat_trimmed' => $vatToCheck,
  124. 'vat_empty_check' => empty($vatToCheck),
  125. 'existing_supplier_id' => $existingSupplier ? $existingSupplier->id : null,
  126. 'existing_supplier_name' => $existingSupplier ? $existingSupplier->name : null,
  127. 'existing_supplier_vat' => $existingSupplier ? $existingSupplier->vat : null,
  128. 'validation_rules' => $this->rules
  129. ]);
  130. if (!empty($vatToCheck)) {
  131. $duplicateCount = \App\Models\Supplier::where('vat', $vatToCheck)->count();
  132. if ($duplicateCount > 0) {
  133. Log::info('VAT duplicate found, adding error');
  134. $this->addError('vat', 'Un fornitore con questa Partita IVA esiste già');
  135. return;
  136. }
  137. }
  138. $fiscalCodeToCheck = trim($this->fiscal_code);
  139. if (!empty($fiscalCodeToCheck)) {
  140. $duplicateFiscalCount = \App\Models\Supplier::where('fiscal_code', $fiscalCodeToCheck)->count();
  141. if ($duplicateFiscalCount > 0) {
  142. Log::info('Fiscal code duplicate found, adding error');
  143. $this->addError('fiscal_code', 'Un fornitore con questo Codice Fiscale esiste già');
  144. return;
  145. }
  146. }
  147. try {
  148. \App\Models\Supplier::create([
  149. 'name' => $this->name,
  150. 'fiscal_code' => !empty($fiscalCodeToCheck) ? $fiscalCodeToCheck : null,
  151. 'vat' => !empty($vatToCheck) ? $vatToCheck : null,
  152. 'address' => $this->address,
  153. 'zip_code' => $this->zip_code,
  154. 'nation_id' => $this->nation_id,
  155. 'province_id' => $this->province_id > 0 ? $this->province_id : null,
  156. 'city_id' => $this->city_id > 0 ? $this->city_id : null,
  157. 'referent' => $this->referent,
  158. 'website' => $this->website,
  159. 'phone' => $this->phone,
  160. 'email' => $this->email,
  161. 'referent_first_name' => $this->referent_first_name,
  162. 'referent_last_name' => $this->referent_last_name,
  163. 'referent_email' => $this->referent_email,
  164. 'referent_phone' => $this->referent_phone,
  165. 'referent_mobile' => $this->referent_mobile,
  166. 'enabled' => $this->enabled
  167. ]);
  168. session()->flash('success', 'Fornitore creato');
  169. $this->resetFields();
  170. $this->add = false;
  171. } catch (\Exception $ex) {
  172. session()->flash('error', 'Errore (' . $ex->getMessage() . ')');
  173. }
  174. }
  175. public function edit($id)
  176. {
  177. $this->emit('load-select');
  178. try {
  179. $supplier = \App\Models\Supplier::findOrFail($id);
  180. if (!$supplier) {
  181. session()->flash('error', 'Fornitore non trovato');
  182. } else {
  183. $this->name = $supplier->name;
  184. $this->fiscal_code = $supplier->fiscal_code;
  185. $this->vat = $supplier->vat;
  186. $this->address = $supplier->address;
  187. $this->zip_code = $supplier->zip_code;
  188. $this->nation_id = $supplier->nation_id;
  189. $this->province_id = $supplier->province_id;
  190. $this->city_id = $supplier->city_id;
  191. $this->referent = $supplier->referent;
  192. $this->website = $supplier->website;
  193. $this->phone = $supplier->phone;
  194. $this->email = $supplier->email;
  195. $this->referent_first_name = $supplier->referent_first_name;
  196. $this->referent_last_name = $supplier->referent_last_name;
  197. $this->referent_email = $supplier->referent_email;
  198. $this->referent_phone = $supplier->referent_phone;
  199. $this->referent_mobile = $supplier->referent_mobile;
  200. $this->enabled = $supplier->enabled;
  201. $this->dataId = $supplier->id;
  202. $this->update = true;
  203. $this->add = false;
  204. $this->checkIsItaly();
  205. $this->emit('load-provinces', $this->nation_id, 'provinceClass');
  206. $this->emit('load-cities', $this->province_id, 'cityClass');
  207. }
  208. } catch (\Exception $ex) {
  209. session()->flash('error', 'Errore (' . $ex->getMessage() . ')');
  210. }
  211. }
  212. public function cancel()
  213. {
  214. $this->add = false;
  215. $this->update = false;
  216. $this->resetFields();
  217. }
  218. // Replace delete method with anonymize method
  219. public function anonymize($id)
  220. {
  221. try {
  222. $supplier = \App\Models\Supplier::findOrFail($id);
  223. // Anonymize all fields
  224. $supplier->update([
  225. 'name' => 'Fornitore Anonimizzato',
  226. 'fiscal_code' => null,
  227. 'vat' => null,
  228. 'address' => null,
  229. 'zip_code' => null,
  230. 'nation_id' => null,
  231. 'province_id' => null,
  232. 'city_id' => null,
  233. 'referent' => null,
  234. 'website' => null,
  235. 'phone' => null,
  236. 'email' => null,
  237. 'referent_first_name' => null,
  238. 'referent_last_name' => null,
  239. 'referent_email' => null,
  240. 'referent_phone' => null,
  241. 'referent_mobile' => null,
  242. 'archived' => true, // Mark as archived
  243. 'enabled' => false // Also disable the supplier
  244. ]);
  245. session()->flash('success', "Fornitore anonimizzato");
  246. return redirect(request()->header('Referer'));
  247. } catch (\Exception $e) {
  248. session()->flash('error', 'Errore (' . $e->getMessage() . ')');
  249. }
  250. }
  251. public function getNation($nation)
  252. {
  253. if ($nation > 0) {
  254. $ret = \App\Models\Nation::findOrFail($nation);
  255. return $ret->name;
  256. }
  257. return "";
  258. }
  259. public function getProvince($province)
  260. {
  261. if ($province > 0) {
  262. $ret = \App\Models\Province::findOrFail($province);
  263. return $ret->name;
  264. }
  265. return "";
  266. }
  267. public function getCity($city)
  268. {
  269. if ($city > 0) {
  270. $ret = \App\Models\City::findOrFail($city);
  271. return $ret->name;
  272. }
  273. return "";
  274. }
  275. protected function getRulesForUpdate()
  276. {
  277. return [
  278. 'name' => 'required',
  279. 'vat' => 'nullable|unique:suppliers,vat,' . $this->dataId,
  280. 'fiscal_code' => 'nullable|unique:suppliers,fiscal_code,' . $this->dataId
  281. ];
  282. }
  283. public function update()
  284. {
  285. // Clean empty fields first
  286. $this->cleanEmptyFields();
  287. $this->validate($this->getRulesForUpdate());
  288. try {
  289. \App\Models\Supplier::whereId($this->dataId)->update([
  290. 'name' => $this->name,
  291. 'fiscal_code' => $this->fiscal_code,
  292. 'vat' => $this->vat,
  293. 'address' => $this->address,
  294. 'zip_code' => $this->zip_code,
  295. 'nation_id' => $this->nation_id,
  296. 'province_id' => $this->province_id > 0 ? $this->province_id : null,
  297. 'city_id' => $this->city_id > 0 ? $this->city_id : null,
  298. 'referent' => $this->referent,
  299. 'website' => $this->website,
  300. 'phone' => $this->phone,
  301. 'email' => $this->email,
  302. 'referent_first_name' => $this->referent_first_name,
  303. 'referent_last_name' => $this->referent_last_name,
  304. 'referent_email' => $this->referent_email,
  305. 'referent_phone' => $this->referent_phone,
  306. 'referent_mobile' => $this->referent_mobile,
  307. 'enabled' => $this->enabled
  308. ]);
  309. session()->flash('success', 'Fornitore aggiornato');
  310. $this->resetFields();
  311. $this->update = false;
  312. } catch (\Exception $ex) {
  313. session()->flash('error', 'Errore (' . $ex->getMessage() . ')');
  314. }
  315. }
  316. }