validate([ 'full_name' => 'string|max:255', 'tax_number' => 'nullable|integer', 'social_security_number' => 'nullable|integer', 'description' => 'nullable|string|max:500' ]); $person->update($attributes); return response()->json([ 'person' => [ 'full_name' => $person->full_name, 'tax_number' => $person->tax_number, 'social_security_number' => $person->social_security_number, 'description' => $person->description ] ]); } public function createAddress(Person $person, Request $request){ $attributes = $request->validate([ 'address' => 'required|string|max:150', 'country' => 'nullable|string', 'type_id' => 'required|integer|exists:address_types,id', 'description' => 'nullable|string|max:125' ]); // Dedup: avoid duplicate address per person by (address, country) $address = $person->addresses()->firstOrCreate([ 'address' => $attributes['address'], 'country' => $attributes['country'] ?? null, ], $attributes); return response()->json([ 'address' => \App\Models\Person\PersonAddress::with(['type'])->findOrFail($address->id) ]); } public function updateAddress(Person $person, int $address_id, Request $request) { $attributes = $request->validate([ 'address' => 'required|string|max:150', 'country' => 'nullable|string', 'type_id' => 'required|integer|exists:address_types,id', 'description' => 'nullable|string|max:125' ]); $address = $person->addresses()->with(['type'])->findOrFail($address_id); $address->update($attributes); return response()->json([ 'address' => $address ]); } public function deleteAddress(Person $person, int $address_id, Request $request) { $address = $person->addresses()->findOrFail($address_id); $address->delete(); // soft delete return response()->json(['status' => 'ok']); } public function createPhone(Person $person, Request $request) { $attributes = $request->validate([ 'nu' => 'required|string|max:50', 'country_code' => 'nullable|integer', 'type_id' => 'required|integer|exists:phone_types,id', 'description' => 'nullable|string|max:125' ]); // Dedup: avoid duplicate phone per person by (nu, country_code) $phone = $person->phones()->firstOrCreate([ 'nu' => $attributes['nu'], 'country_code' => $attributes['country_code'] ?? null, ], $attributes); return response()->json([ 'phone' => \App\Models\Person\PersonPhone::with(['type'])->findOrFail($phone->id) ]); } public function updatePhone(Person $person, int $phone_id, Request $request) { $attributes = $request->validate([ 'nu' => 'required|string|max:50', 'country_code' => 'nullable|integer', 'type_id' => 'required|integer|exists:phone_types,id', 'description' => 'nullable|string|max:125' ]); $phone = $person->phones()->with(['type'])->findOrFail($phone_id); $phone->update($attributes); return response()->json([ 'phone' => $phone ]); } public function deletePhone(Person $person, int $phone_id, Request $request) { $phone = $person->phones()->findOrFail($phone_id); $phone->delete(); // soft delete return response()->json(['status' => 'ok']); } public function createEmail(Person $person, Request $request) { $attributes = $request->validate([ 'value' => 'required|email:rfc,dns|max:255', 'label' => 'nullable|string|max:50', 'is_primary' => 'boolean', 'is_active' => 'boolean', 'valid' => 'boolean', 'verified_at' => 'nullable|date', 'preferences' => 'nullable|array', 'meta' => 'nullable|array', ]); // Dedup: avoid duplicate email per person by value $email = $person->emails()->firstOrCreate([ 'value' => $attributes['value'], ], $attributes); return response()->json([ 'email' => \App\Models\Email::findOrFail($email->id) ]); } public function updateEmail(Person $person, int $email_id, Request $request) { $attributes = $request->validate([ 'value' => 'required|email:rfc,dns|max:255', 'label' => 'nullable|string|max:50', 'is_primary' => 'boolean', 'is_active' => 'boolean', 'valid' => 'boolean', 'verified_at' => 'nullable|date', 'preferences' => 'nullable|array', 'meta' => 'nullable|array', ]); $email = $person->emails()->findOrFail($email_id); $email->update($attributes); return response()->json([ 'email' => $email ]); } public function deleteEmail(Person $person, int $email_id, Request $request) { $email = $person->emails()->findOrFail($email_id); $email->delete(); return response()->json(['status' => 'ok']); } // TRR (bank account) CRUD public function createTrr(Person $person, Request $request) { $attributes = $request->validate([ 'iban' => 'nullable|string|max:34', 'bank_name' => 'required|string|max:100', 'bic_swift' => 'nullable|string|max:11', 'account_number' => 'nullable|string|max:34', 'routing_number' => 'nullable|string|max:20', 'currency' => 'required|string|size:3', 'country_code' => 'nullable|string|size:2', 'holder_name' => 'nullable|string|max:125', 'notes' => 'nullable|string', 'meta' => 'nullable|array', ]); // Create without dedup (IBAN may be null or vary); could dedup by IBAN if provided $trr = $person->bankAccounts()->create($attributes); return response()->json([ 'trr' => BankAccount::findOrFail($trr->id) ]); } public function updateTrr(Person $person, int $trr_id, Request $request) { $attributes = $request->validate([ 'iban' => 'nullable|string|max:34', 'bank_name' => 'required|string|max:100', 'bic_swift' => 'nullable|string|max:11', 'account_number' => 'nullable|string|max:34', 'routing_number' => 'nullable|string|max:20', 'currency' => 'required|string|size:3', 'country_code' => 'nullable|string|size:2', 'holder_name' => 'nullable|string|max:125', 'notes' => 'nullable|string', 'meta' => 'nullable|array', 'is_active' => 'sometimes|boolean', ]); $trr = $person->bankAccounts()->findOrFail($trr_id); $trr->update($attributes); return response()->json([ 'trr' => $trr ]); } public function deleteTrr(Person $person, int $trr_id, Request $request) { $trr = $person->bankAccounts()->findOrFail($trr_id); $trr->delete(); return response()->json(['status' => 'ok']); } }