Add salutation field to contacts #13

This commit is contained in:
2025-10-29 13:53:08 +01:00
parent a34226c6a9
commit 59c2b9c28c
10 changed files with 26 additions and 13 deletions
@@ -12,6 +12,7 @@ public function index()
return [ return [
'id' => $contact->id, 'id' => $contact->id,
'customerId' => $contact->customer_id, 'customerId' => $contact->customer_id,
'salutation' => $contact->salutation,
'firstName' => $contact->first_name, 'firstName' => $contact->first_name,
'lastName' => $contact->last_name, 'lastName' => $contact->last_name,
'email' => $contact->email, 'email' => $contact->email,
@@ -36,6 +37,7 @@ public function show($id)
return [ return [
'id' => $contact->id, 'id' => $contact->id,
'customerId' => $contact->customer_id, 'customerId' => $contact->customer_id,
'salutation' => $contact->salutation,
'firstName' => $contact->first_name, 'firstName' => $contact->first_name,
'lastName' => $contact->last_name, 'lastName' => $contact->last_name,
'email' => $contact->email, 'email' => $contact->email,
@@ -344,6 +344,7 @@ public function store(Request $request)
'billingData.billingAddress.city' => 'nullable|string', 'billingData.billingAddress.city' => 'nullable|string',
'billingData.billingAddress.postalCode' => 'nullable|string', 'billingData.billingAddress.postalCode' => 'nullable|string',
'billingData.billingAddress.countryCode' => 'nullable|string', 'billingData.billingAddress.countryCode' => 'nullable|string',
'billingData.contactSalutation' => 'nullable|string',
'billingData.contactFirstName' => 'nullable|string', 'billingData.contactFirstName' => 'nullable|string',
'billingData.contactLastName' => 'nullable|string', 'billingData.contactLastName' => 'nullable|string',
'billingData.paymentTerms' => 'nullable|array', 'billingData.paymentTerms' => 'nullable|array',
@@ -428,6 +429,7 @@ public function update(Request $request, $id)
'billingData.billingAddress.city' => 'nullable|string', 'billingData.billingAddress.city' => 'nullable|string',
'billingData.billingAddress.postalCode' => 'nullable|string', 'billingData.billingAddress.postalCode' => 'nullable|string',
'billingData.billingAddress.countryCode' => 'nullable|string', 'billingData.billingAddress.countryCode' => 'nullable|string',
'billingData.contactSalutation' => 'nullable|string',
'billingData.contactFirstName' => 'nullable|string', 'billingData.contactFirstName' => 'nullable|string',
'billingData.contactLastName' => 'nullable|string', 'billingData.contactLastName' => 'nullable|string',
'billingData.paymentTerms' => 'nullable|array', 'billingData.paymentTerms' => 'nullable|array',
+1
View File
@@ -11,6 +11,7 @@ class Contact extends Model
protected $fillable = [ protected $fillable = [
'customer_id', 'customer_id',
'salutation',
'first_name', 'first_name',
'last_name', 'last_name',
'email', 'email',
+5 -2
View File
@@ -20,9 +20,12 @@ public function definition()
$avatar = "https://i.pravatar.cc/128?img={$randomImageId}"; $avatar = "https://i.pravatar.cc/128?img={$randomImageId}";
} }
$gender = rand(0, 9) >= 5 ? 'female' : 'male';
return [ return [
'first_name' => $this->faker->firstName(), 'salutation' => $this->faker->title($gender),
'last_name' => $this->faker->lastName(), 'first_name' => $this->faker->firstName($gender),
'last_name' => $this->faker->lastName($gender),
'email' => $this->faker->unique()->safeEmail(), 'email' => $this->faker->unique()->safeEmail(),
'phone' => $this->faker->phoneNumber(), 'phone' => $this->faker->phoneNumber(),
'position' => $this->faker->jobTitle(), 'position' => $this->faker->jobTitle(),
@@ -11,6 +11,7 @@ public function up()
Schema::create('contacts', function (Blueprint $table) { Schema::create('contacts', function (Blueprint $table) {
$table->id(); $table->id();
$table->foreignId('customer_id')->constrained()->onDelete('cascade'); $table->foreignId('customer_id')->constrained()->onDelete('cascade');
$table->string('salutation', 20);
$table->string('first_name', 50); $table->string('first_name', 50);
$table->string('last_name', 50); $table->string('last_name', 50);
$table->string('email', 100)->nullable(); $table->string('email', 100)->nullable();
+1
View File
@@ -120,6 +120,7 @@ const saveInvoice = async (updatedInvoice: Invoice) => {
companyName: updatedInvoice.billingData?.companyName, companyName: updatedInvoice.billingData?.companyName,
vatId: updatedInvoice.billingData?.vatId, vatId: updatedInvoice.billingData?.vatId,
billingAddress: updatedInvoice.billingData?.billingAddress, billingAddress: updatedInvoice.billingData?.billingAddress,
contactSalutation: updatedInvoice.billingData?.contactSalutation,
contactFirstName: updatedInvoice.billingData?.contactFirstName, contactFirstName: updatedInvoice.billingData?.contactFirstName,
contactLastName: updatedInvoice.billingData?.contactLastName, contactLastName: updatedInvoice.billingData?.contactLastName,
paymentTerms: updatedInvoice.billingData?.paymentTerms paymentTerms: updatedInvoice.billingData?.paymentTerms
+3
View File
@@ -86,6 +86,7 @@ export type ContactType = Contact
export function newContact(): Contact { export function newContact(): Contact {
return { return {
id: 0, id: 0,
salutation: '',
firstName: '', firstName: '',
lastName: '', lastName: '',
email: '', email: '',
@@ -146,6 +147,7 @@ export interface Invoice {
companyName: string | null; companyName: string | null;
vatId: string | null; vatId: string | null;
billingAddress: Address | null; billingAddress: Address | null;
contactSalutation: string | null;
contactFirstName: string | null; contactFirstName: string | null;
contactLastName: string | null; contactLastName: string | null;
paymentTerms: PaymentTerms | null; paymentTerms: PaymentTerms | null;
@@ -181,6 +183,7 @@ export function newBillingData() {
companyName: "", companyName: "",
vatId: "", vatId: "",
billingAddress: newAddress(), billingAddress: newAddress(),
contactSalutation: "",
contactFirstName: "", contactFirstName: "",
contactLastName: "", contactLastName: "",
paymentTerms: newPaymentTerms() paymentTerms: newPaymentTerms()
@@ -178,7 +178,7 @@
<table width="636" cellpadding="0" cellspacing="0" border="0" class="container"> <table width="636" cellpadding="0" cellspacing="0" border="0" class="container">
<tr> <tr>
<td align="left" valign="top"> <td align="left" valign="top">
<p>Hallo {{ $invoice['billingData']['contactSalutation'] ?? '' }} {{ $invoice['billingData']['contactLastName'] }},</p> <p>Hallo {{ $invoice['billingData']['contactSalutation'] ?? 'Herr/Frau' }} {{ $invoice['billingData']['contactLastName'] }},</p>
<p>uns ist aufgefallen, dass die hier aufgeführten Rechnungsbeträge noch nicht beglichen wurden.</p> <p>uns ist aufgefallen, dass die hier aufgeführten Rechnungsbeträge noch nicht beglichen wurden.</p>
</td> </td>
</tr> </tr>
@@ -182,7 +182,7 @@
<table width="636" cellpadding="0" cellspacing="0" border="0" class="container"> <table width="636" cellpadding="0" cellspacing="0" border="0" class="container">
<tr> <tr>
<td align="left" valign="top"> <td align="left" valign="top">
<p>Hallo {{ $offer['contact']['salutation'] ?? '' }} {{ <p>Hallo {{ $offer['contact']['salutation'] ?? 'Herr/Frau' }} {{
$offer['contact']['lastName'] }},</p> $offer['contact']['lastName'] }},</p>
<p>wir bedanken uns herzlich für Ihren Auftrag und bestätigen Ihnen hiermit <p>wir bedanken uns herzlich für Ihren Auftrag und bestätigen Ihnen hiermit
den Eingang und die Annahme Ihres Auftrags vom {{ den Eingang und die Annahme Ihres Auftrags vom {{
+8 -8
View File
@@ -28,11 +28,11 @@
Route::get('/invoices/{id}/remind', function ($id) { Route::get('/invoices/{id}/remind', function ($id) {
$invoice = InvoiceController::single($id); $invoice = InvoiceController::single($id);
Mail::to('daniel@vollstock.de')->send(new Reminder($invoice)); // Mail::to('daniel@vollstock.de')->send(new Reminder($invoice));
// return new Reminder($invoice); return new Reminder($invoice);
}); });
Route::get('/offers/{id}/confirmation', function ($id) { Route::get('/offers/{id}/confirm', function ($id) {
// $offer = offerController::single($id); // $offer = offerController::single($id);
$offer = [ $offer = [
'nr' => 0, 'nr' => 0,
@@ -52,23 +52,23 @@
], ],
'contact' => [ 'contact' => [
'salutation' => 'Frau', 'salutation' => 'Frau',
'firstName' => '', 'firstName' => 'Claudia',
'lastName' => '', 'lastName' => 'Mustermann',
'email' => '', 'email' => '',
'phone' => '', 'phone' => '',
'position' => null, 'position' => null,
'isPrimary' => false, 'isPrimary' => false,
'avatar' => null, 'avatar' => null,
], ],
'totalAmount' => '13575.88', 'totalAmount' => '84.033',
'title' => "", 'title' => "Angebots-Titel",
'text' => '', 'text' => '',
'items' => [], 'items' => [],
'paymentTerms' => [ 'paymentTerms' => [
'name' => 'onReceipt', 'name' => 'onReceipt',
'description' => 'Bei Rechnungserhalt', 'description' => 'Bei Rechnungserhalt',
'isFixed' => true, 'isFixed' => true,
'days' => null, 'days' => 14,
] ]
]; ];