# Create new ticket

## createTicket()

This gets called when a customer creates a new ticket in the storefront. This gets called in the following file:

```php
app/Http/Controllers/Storefront/Account/SupportTicketController.php Line 125
```

### Parameters

<table><thead><tr><th width="142">Type</th><th width="166">Name</th><th>Description</th></tr></thead><tbody><tr><td>SalesChannel</td><td>salesChannel</td><td>The salesChannel</td></tr><tr><td>Customer or null</td><td>customer</td><td>The Customer object. If null, then guestName and guestMail is filled. (The ticket was created without login using contact forms)</td></tr><tr><td>string</td><td>subject</td><td>The ticket subject.</td></tr><tr><td>string</td><td>message</td><td>The initial message.</td></tr><tr><td>ProductHosting or Domain or null</td><td>product</td><td>The selected ProductHosting or Domain or null. Check with instanceof()</td></tr><tr><td>TicketDepartment or null</td><td>department</td><td>The selected Department </td></tr><tr><td>array</td><td>attachments</td><td>Array of ticket attachments</td></tr><tr><td>String or null</td><td>guestName</td><td>If customer is null, this contains the guest name</td></tr><tr><td>String or null</td><td>guestMail</td><td>If customer is null, this contains the guest email</td></tr></tbody></table>

### Response

TicketCreatedResponse() class.

<table><thead><tr><th width="142">Type</th><th width="166">Name</th><th>Description</th></tr></thead><tbody><tr><td>mixed</td><td>$id</td><td>The ID of the ticked. Usually integer or UUID.</td></tr><tr><td>mixed</td><td>$number</td><td>The number of the ticket which was created during generation.</td></tr><tr><td>mixed</td><td>$messageId</td><td>The ID of the initial message.</td></tr><tr><td>array</td><td>$attachmentFilePaths</td><td>Array of file paths in the same order as the files.</td></tr></tbody></table>

### Example Code

```php
public function createTicket(
	SalesChannel      $salesChannel,
	?Customer         $customer,
	string            $subject,
	string            $message,
	mixed             $product,
	?TicketDepartment $department = null,
	array             $attachments = [],
	?string           $guestName = null,
	?string           $guestMail = null,
): TicketCreatedResponse {
	$mailboxId = $department->provider_department_id["freescout"] ?? $this->provider->default_department_id;
	$customerId = $this->getCustomerId($customer, $guestName, $guestMail);
	$additionalTexts = [];


	if($customer !== null) {
		$customerViewUrl = $salesChannel->url . route('admin.customer.edit', $customer->id, false);
		$additionalTexts = [
			"Ticket aus hostware in Freescout erstellt",
			"Verkaufskanal: {$salesChannel->name}",
			"<a href='{$customerViewUrl}'>Kunde ansehen (#{$customer->customer_number})</a>"
		];

		if ($product !== null) {
			$productRoute = "N-A";
			$productText = "N/A";

			if ($product instanceof Domain) {
				$productRoute = route('admin.domain.view', $product->fqdn, false);
				$productText = "{$product->fqdn} (Domain)";
			}
			if ($product instanceof ProductHosting) {
				$productRoute = route('admin.hosting.hostings.view', $product->id, false);
				$productText = "{$product->product->name} #{$product->product_hosting_number} (Hosting)";
			}

			$completeUrl = $salesChannel->url . $productRoute;

			$additionalTexts[] = '<a href="' . $completeUrl . '">Verlinktes Produkt ansehen (' . $productText . ')</a>';
		}
	}

	$threadAttachments = [];
	foreach ($attachments as $attachment) {
		$threadAttachments[] = [
			'fileName' => $attachment->getClientOriginalName(),
			'mimeType' => $attachment->getMimeType(),
			'data' => base64_encode($attachment->getContent()),
		];
	}


	$response = $this->makeRequest("conversations", "POST", [
		"type" => "email",
		"mailboxId" => $mailboxId,
		"subject" => $subject,
		"customer" => [
			'id' => $customerId,
		],
		"threads" => [[
			'text' => $message,
			'type' => 'customer',
			'customer' => [
				'id' => $customerId,
			],
			"attachments" => $threadAttachments
		], [
			'text' => implode("<br>", $additionalTexts),
			'type' => 'note',
			'user' => $this->_getFreescoutUserId()
		]],
		"createdAt" => now()->setTimezone("UTC")->toISOString(),
		"status" => "active"
	]);

	/**
	 * Get the attachment IDs
	 */
	$attachmentResponse = [];
	foreach ($response->_embedded->threads[0]->_embedded->attachments as $file) {
		$attachmentResponse[] = $file->id;
	}


	Log::debug("Freescout ticket creation response", ["res" => $response]);

	return new TicketCreatedResponse(
		$response->id,
		$response->number,
		$response->_embedded->threads[0]->id,
		$attachmentResponse
	);
}

/**
The function below is not required by the interface, but it gets used in the createTicket() of Freescout.

This method searches or creates a customer / contact at the ticket api using the given customer.
*/
private function getCustomerId(?Customer $customer, ?string $guestName = null, ?string $guestMail = null,) {
	if($customer === null) {
		/**
		 * Create a guest in freescout
		 */
		$allCustomers = $this->makeRequest("customers", "GET", [
			"email" => $guestMail
		]);

		if (count($allCustomers->_embedded->customers) === 1) {
			return $allCustomers->_embedded->customers[0]->id;
		}

		$response = $this->makeRequest("customers", "POST", [
			"firstName" => $guestName,
			"lastName" => "-",
			"notes" => "Aus hostware als Gast erstellt",
			"emails" => [[
				'value' => $guestMail,
				'type' => 'home',
			]]
		]);

		return $response->id;
	}

	/**
	If the customer already has a contact saved in the hostware database, use that.
	**/
	if (isset($customer->support_ticket_providers['freescout'])) {
		return $customer->support_ticket_providers['freescout'];
	}


	/**
	 * Search existing customers for the email
	 */
	$allCustomers = $this->makeRequest("customers", "GET", [
		"email" => $customer->email
	]);

	if (count($allCustomers->_embedded->customers) === 1) {
		$customer->addTicketProviderId("freescout", $allCustomers->_embedded->customers[0]->id);

		return $allCustomers->_embedded->customers[0]->id;
	}


	/**
	If no existing contact was found, create a new one.
	*/
	$firstAddress = $customer->firstAddress();
	$customerViewUrl = $customer->salesChannel->url . route('admin.customer.edit', $customer->id, false);

	$response = $this->makeRequest("customers", "POST", [
		"firstName" => $customer->first_name,
		"lastName" => $customer->last_name,
		"phone" => $customer->phone,
		"photoUrl" => null,
		"jobTitle" => null,
		"photoType" => null,
		"address" => array(
			'city' => $firstAddress->city,
			'state' => '-',
			'zip' => $firstAddress->zipcode,
			'country' => $firstAddress->country,
			'address' => $firstAddress->street_full,
		),
		"notes" => "Aus hostware importiert\n\n{$customerViewUrl}",
		"company" => $customer->company,
		"emails" => [[
			'value' => $customer->email,
			'type' => 'home',
		]],
		"phones" => [[
			'value' => $customer->phone,
			'type' => 'home',
		]]
	]);

	// Save the contact id to customer in hostware.
	$customer->addTicketProviderId("freescout", $response->id);
	return $response->id;
}
```

### Testing

You can test this function by creating a ticket in the storefront.
