diff --git a/api/ApplicationContext.php b/api/ApplicationContext.php index 08c26c40..76de8849 100644 --- a/api/ApplicationContext.php +++ b/api/ApplicationContext.php @@ -13,6 +13,7 @@ use BusinessLogic\Tickets\TrackingIdGenerator; use DataAccess\Categories\CategoryGateway; use DataAccess\Security\BanGateway; use DataAccess\Security\UserGateway; +use DataAccess\Statuses\StatusGateway; use DataAccess\Tickets\TicketGateway; @@ -35,6 +36,7 @@ class ApplicationContext { $this->get[BanRetriever::class] = new BanRetriever($this->get[BanGateway::class]); // Tickets + $this->get[StatusGateway::class] = new StatusGateway(); $this->get[TicketGateway::class] = new TicketGateway(); $this->get[TicketRetriever::class] = new TicketRetriever($this->get[TicketGateway::class]); $this->get[TicketValidators::class] = new TicketValidators($this->get[TicketGateway::class]); @@ -46,6 +48,7 @@ class ApplicationContext { $this->get[TicketCreator::class] = new TicketCreator($this->get[NewTicketValidator::class], $this->get[TrackingIdGenerator::class], $this->get[Autoassigner::class], + $this->get[StatusGateway::class], $this->get[TicketGateway::class]); } } \ No newline at end of file diff --git a/api/BusinessLogic/Statuses/DefaultStatusForAction.php b/api/BusinessLogic/Statuses/DefaultStatusForAction.php index 569fe224..ac9a7805 100644 --- a/api/BusinessLogic/Statuses/DefaultStatusForAction.php +++ b/api/BusinessLogic/Statuses/DefaultStatusForAction.php @@ -18,5 +18,19 @@ class DefaultStatusForAction { const REOPENED_BY_STAFF = "IsStaffReopenedStatus"; const DEFAULT_STAFF_REPLY = "IsDefaultStaffReplyStatus"; const LOCKED_TICKET = "LockedTicketStatus"; - const AUTOCLOSE_STATUS = "IsAutoCloseOption"; + const AUTOCLOSE_STATUS = "IsAutocloseOption"; + + static function getAll() { + return array( + self::NEW_TICKET, + self::CLOSED_STATUS, + self::CLOSED_BY_CLIENT, + self::CUSTOMER_REPLY, + self::CLOSED_BY_STAFF, + self::REOPENED_BY_STAFF, + self::DEFAULT_STAFF_REPLY, + self::LOCKED_TICKET, + self::AUTOCLOSE_STATUS + ); + } } \ No newline at end of file diff --git a/api/BusinessLogic/Statuses/Status.php b/api/BusinessLogic/Statuses/Status.php index 89c8db3e..615abf75 100644 --- a/api/BusinessLogic/Statuses/Status.php +++ b/api/BusinessLogic/Statuses/Status.php @@ -4,6 +4,42 @@ namespace BusinessLogic\Statuses; class Status { + static function fromDatabase($row, $languageRs) { + $status = new Status(); + $status->id = $row['ID']; + $status->textColor = $row['TextColor']; + $status->defaultActions = array(); + + foreach (DefaultStatusForAction::getAll() as $defaultStatus) { + $status = self::addDefaultStatusIfSet($status, $row, $defaultStatus); + } + + $status->closable = $row['Closable']; + + $localizedLanguages = array(); + while ($languageRow = hesk_dbFetchAssoc($languageRs)) { + $localizedLanguages[] = new StatusLanguage($languageRow['language'], $languageRow['text']); + } + $status->localizedNames = $localizedLanguages; + $status->sort = $row['sort']; + + return $status; + } + + /** + * @param $status Status + * @param $row array + * @param $key string + * @return Status + */ + private static function addDefaultStatusIfSet($status, $row, $key) { + if ($row[$key]) { + $status->defaultActions[] = $key; + } + + return $status; + } + /** * @var $id int */ @@ -30,7 +66,7 @@ class Status { public $sort; /** - * @var $name string[] + * @var $name StatusLanguage[] */ public $localizedNames; } \ No newline at end of file diff --git a/api/BusinessLogic/Statuses/StatusLanguage.php b/api/BusinessLogic/Statuses/StatusLanguage.php new file mode 100644 index 00000000..181a04a0 --- /dev/null +++ b/api/BusinessLogic/Statuses/StatusLanguage.php @@ -0,0 +1,20 @@ +language = $language; + $this->text = $text; + } +} \ No newline at end of file diff --git a/api/BusinessLogic/Tickets/TicketCreator.php b/api/BusinessLogic/Tickets/TicketCreator.php index c723fafd..7d6c5687 100644 --- a/api/BusinessLogic/Tickets/TicketCreator.php +++ b/api/BusinessLogic/Tickets/TicketCreator.php @@ -3,6 +3,8 @@ namespace BusinessLogic\Tickets; use BusinessLogic\Exceptions\ValidationException; +use BusinessLogic\Statuses\DefaultStatusForAction; +use DataAccess\Statuses\StatusGateway; use DataAccess\Tickets\TicketGateway; class TicketCreator { @@ -21,15 +23,21 @@ class TicketCreator { */ private $autoassigner; + /** + * @var $statusGateway StatusGateway + */ + private $statusGateway; + /** * @var $ticketGateway TicketGateway */ private $ticketGateway; - function __construct($newTicketValidator, $trackingIdGenerator, $autoassigner, $ticketGateway) { + function __construct($newTicketValidator, $trackingIdGenerator, $autoassigner, $statusGateway, $ticketGateway) { $this->newTicketValidator = $newTicketValidator; $this->trackingIdGenerator = $trackingIdGenerator; $this->autoassigner = $autoassigner; + $this->statusGateway = $statusGateway; $this->ticketGateway = $ticketGateway; } @@ -76,10 +84,25 @@ class TicketCreator { $ticket->ipAddress = $ticketRequest->ipAddress; $ticket->language = $ticketRequest->language; + $status = $this->statusGateway->getStatusForDefaultAction(DefaultStatusForAction::NEW_TICKET, $heskSettings); + + if ($status === null) { + throw new \Exception("Could not find the default status for a new ticket!"); + } + $ticket->statusId = $status->id; + $ticketGatewayGeneratedFields = $this->ticketGateway->createTicket($ticket, $heskSettings); $ticket->dateCreated = $ticketGatewayGeneratedFields->dateCreated; $ticket->lastChanged = $ticketGatewayGeneratedFields->dateModified; + $ticket->archived = false; + $ticket->locked = false; + $ticket->id = $ticketGatewayGeneratedFields->id; + $ticket->openedBy = 0; + $ticket->numberOfReplies = 0; + $ticket->numberOfStaffReplies = 0; + $ticket->timeWorked = '00:00:00'; + $ticket->lastReplier = 0; return $ticket; } diff --git a/api/BusinessLogic/Tickets/TicketGatewayGeneratedFields.php b/api/BusinessLogic/Tickets/TicketGatewayGeneratedFields.php index 00d9521b..49f2f2ac 100644 --- a/api/BusinessLogic/Tickets/TicketGatewayGeneratedFields.php +++ b/api/BusinessLogic/Tickets/TicketGatewayGeneratedFields.php @@ -10,6 +10,7 @@ namespace BusinessLogic\Tickets; class TicketGatewayGeneratedFields { + public $id; public $dateCreated; public $dateModified; } \ No newline at end of file diff --git a/api/DataAccess/Statuses/StatusGateway.php b/api/DataAccess/Statuses/StatusGateway.php index c244f19e..de812784 100644 --- a/api/DataAccess/Statuses/StatusGateway.php +++ b/api/DataAccess/Statuses/StatusGateway.php @@ -5,15 +5,31 @@ namespace DataAccess\Statuses; use BusinessLogic\Statuses\DefaultStatusForAction; use BusinessLogic\Statuses\Status; +use DataAccess\CommonDao; -class StatusGateway { +class StatusGateway extends CommonDao { /** - * @param $defaultAction DefaultStatusForAction + * @param $defaultAction string * @return Status */ - function getStatusForDefaultAction($defaultAction) { - //-- TODO - return new Status(); + function getStatusForDefaultAction($defaultAction, $heskSettings) { + $this->init(); + + $metaRs = hesk_dbQuery('SELECT * FROM `' . hesk_dbEscape($heskSettings['db_pfix']) . 'statuses` + WHERE `' . $defaultAction . '` = 1'); + if (hesk_dbNumRows($metaRs) === 0) { + return null; + } + $row = hesk_dbFetchAssoc($metaRs); + + $languageRs = hesk_dbQuery('SELECT * FROM `' . hesk_dbEscape($heskSettings['db_pfix']) . 'text_to_status_xref` + WHERE `status_id` = ' . intval($row['ID'])); + + $status = Status::fromDatabase($row, $languageRs); + + $this->close(); + + return $status; } } \ No newline at end of file diff --git a/api/DataAccess/Tickets/TicketGateway.php b/api/DataAccess/Tickets/TicketGateway.php index ae5c2b4d..625c58f9 100644 --- a/api/DataAccess/Tickets/TicketGateway.php +++ b/api/DataAccess/Tickets/TicketGateway.php @@ -92,6 +92,8 @@ class TicketGateway extends CommonDao { function createTicket($ticket, $heskSettings) { global $hesklang; + $this->init(); + $dueDate = $ticket->dueDate ? "'{$ticket->dueDate}'" : "NULL"; // Prepare SQL for custom fields $customWhere = ''; @@ -103,17 +105,17 @@ class TicketGateway extends CommonDao { $customWhat .= ", '" . (isset($ticket->customFields[$i]) ? hesk_dbEscape($ticket->customFields[$i]) : '') . "'"; } - $suggestedArticles = ''; + $suggestedArticles = 'NULL'; if ($ticket->suggestedArticles !== null && !empty($ticket->suggestedArticles)) { - $suggestedArticles = implode(',', $ticket->suggestedArticles); + $suggestedArticles = "'" .implode(',', $ticket->suggestedArticles) . "'"; } $latitude = $ticket->location !== null && isset($ticket->location[0]) - && $ticket->location[0] !== null ? $ticket->location[0] : ''; + && $ticket->location[0] !== null ? $ticket->location[0] : 'E-0'; $longitude = $ticket->location !== null && isset($ticket->location[1]) - && $ticket->location[1] !== null ? $ticket->location[1] : ''; + && $ticket->location[1] !== null ? $ticket->location[1] : 'E-0'; $userAgent = $ticket->userAgent !== null ? $ticket->userAgent : ''; $screenResolutionWidth = $ticket->screenResolution !== null && isset($ticket->screenResolution[0]) @@ -165,8 +167,8 @@ class TicketGateway extends CommonDao { '" . hesk_dbEscape($ticket->message) . "', NOW(), NOW(), - '" . $suggestedArticles . "', - '" . hesk_dbEscape($ticket->ipAddress) . "', + " . $suggestedArticles . ", + '" . hesk_dbEscape($ipAddress) . "', '" . hesk_dbEscape($ticket->language) . "', '" . intval($ticket->openedBy) . "', '" . intval($ticket->ownerId) . "', @@ -186,14 +188,18 @@ class TicketGateway extends CommonDao { "; hesk_dbQuery($sql); + $id = hesk_dbInsertID(); - $rs = hesk_dbQuery('SELECT `dt`, `lastchange` FROM `' . hesk_dbEscape($heskSettings['db_pfix']) . 'tickets` WHERE `id` = ' . intval(hesk_dbInsertID())); + $rs = hesk_dbQuery('SELECT `dt`, `lastchange` FROM `' . hesk_dbEscape($heskSettings['db_pfix']) . 'tickets` WHERE `id` = ' . intval($id)); $row = hesk_dbFetchAssoc($rs); $generatedFields = new TicketGatewayGeneratedFields(); + $generatedFields->id = $id; $generatedFields->dateCreated = $row['dt']; $generatedFields->dateModified = $row['lastchange']; + $this->close(); + return $generatedFields; } } \ No newline at end of file diff --git a/api/Tests/BusinessLogic/Tickets/TicketCreatorTests/CreateTicketForCustomerTest.php b/api/Tests/BusinessLogic/Tickets/TicketCreatorTests/CreateTicketForCustomerTest.php index 967466ca..3a7f7086 100644 --- a/api/Tests/BusinessLogic/Tickets/TicketCreatorTests/CreateTicketForCustomerTest.php +++ b/api/Tests/BusinessLogic/Tickets/TicketCreatorTests/CreateTicketForCustomerTest.php @@ -10,6 +10,8 @@ namespace BusinessLogic\Tickets\TicketCreatorTests; use BusinessLogic\Security\UserContext; +use BusinessLogic\Statuses\DefaultStatusForAction; +use BusinessLogic\Statuses\Status; use BusinessLogic\Tickets\Autoassigner; use BusinessLogic\Tickets\CreateTicketByCustomerModel; use BusinessLogic\Tickets\NewTicketValidator; @@ -18,6 +20,7 @@ use BusinessLogic\Tickets\TicketGatewayGeneratedFields; use BusinessLogic\Tickets\TrackingIdGenerator; use BusinessLogic\ValidationModel; use Core\Constants\Priority; +use DataAccess\Statuses\StatusGateway; use DataAccess\Tickets\TicketGateway; use PHPUnit\Framework\TestCase; @@ -43,6 +46,11 @@ class CreateTicketTest extends TestCase { */ private $autoassigner; + /** + * @var $statusGateway \PHPUnit_Framework_MockObject_MockObject + */ + private $statusGateway; + /** * @var $ticketRequest CreateTicketByCustomerModel */ @@ -78,8 +86,10 @@ class CreateTicketTest extends TestCase { $this->newTicketValidator = $this->createMock(NewTicketValidator::class); $this->trackingIdGenerator = $this->createMock(TrackingIdGenerator::class); $this->autoassigner = $this->createMock(Autoassigner::class); + $this->statusGateway = $this->createMock(StatusGateway::class); - $this->ticketCreator = new TicketCreator($this->newTicketValidator, $this->trackingIdGenerator, $this->autoassigner, $this->ticketGateway); + $this->ticketCreator = new TicketCreator($this->newTicketValidator, $this->trackingIdGenerator, + $this->autoassigner, $this->statusGateway, $this->ticketGateway); $this->ticketRequest = new CreateTicketByCustomerModel(); $this->ticketRequest->name = 'Name'; @@ -105,6 +115,11 @@ class CreateTicketTest extends TestCase { $this->autoassigner->method('getNextUserForTicket')->willReturn(1); $this->ticketGatewayGeneratedFields = new TicketGatewayGeneratedFields(); $this->ticketGateway->method('createTicket')->willReturn($this->ticketGatewayGeneratedFields); + + $status = new Status(); + $status->id = 1; + $this->statusGateway->method('getStatusForDefaultAction') + ->willReturn($status); } function testItSavesTheTicketToTheDatabase() { @@ -185,7 +200,7 @@ class CreateTicketTest extends TestCase { //-- Arrange $this->ticketGatewayGeneratedFields->dateCreated = 'date created'; $this->ticketGatewayGeneratedFields->dateModified = 'date modified'; - + $this->ticketGatewayGeneratedFields->id = 50; //-- Act $ticket = $this->ticketCreator->createTicketByCustomer($this->ticketRequest, $this->heskSettings, $this->modsForHeskSettings, $this->userContext); @@ -193,5 +208,28 @@ class CreateTicketTest extends TestCase { //-- Assert self::assertThat($ticket->dateCreated, self::equalTo($this->ticketGatewayGeneratedFields->dateCreated)); self::assertThat($ticket->lastChanged, self::equalTo($this->ticketGatewayGeneratedFields->dateModified)); + self::assertThat($ticket->id, self::equalTo($this->ticketGatewayGeneratedFields->id)); + } + + function testItSetsTheDefaultStatus() { + //-- Act + $ticket = $this->ticketCreator->createTicketByCustomer($this->ticketRequest, $this->heskSettings, $this->modsForHeskSettings, $this->userContext); + + //-- Assert + self::assertThat($ticket->statusId, self::equalTo(1)); + } + + function testItSetsTheDefaultProperties() { + //-- Act + $ticket = $this->ticketCreator->createTicketByCustomer($this->ticketRequest, $this->heskSettings, $this->modsForHeskSettings, $this->userContext); + + //-- Assert + self::assertThat($ticket->archived, self::isFalse()); + self::assertThat($ticket->locked, self::isFalse()); + self::assertThat($ticket->openedBy, self::equalTo(0)); + self::assertThat($ticket->numberOfReplies, self::equalTo(0)); + self::assertThat($ticket->numberOfStaffReplies, self::equalTo(0)); + self::assertThat($ticket->timeWorked, self::equalTo('00:00:00')); + self::assertThat($ticket->lastReplier, self::equalTo(0)); } }