* multiple team kanban board implementation added

* active flag is now working as intended
* iframe slide type added
* team-slide connection is now many-to-many
This commit is contained in:
Dávid Danyi 2018-09-05 17:01:40 +02:00
parent c096510b3d
commit cfc388aa77
10 changed files with 364 additions and 121 deletions

27
config/autoload/local.php.dist Normal file → Executable file
View File

@ -9,4 +9,31 @@
declare(strict_types=1); declare(strict_types=1);
return [ return [
'app.config' => [
'jira.user' => '',
'jira.password' => '',
'url.jiraAvatar' => 'https://cc-jira.rnd.ki.sw.ericsson.se/secure/useravatar?ownerId=%s',
'url.jiraIssue' => 'https://cc-jira.rnd.ki.sw.ericsson.se/rest/api/2/issue/%s?fields=%s',
'url.jiraKanbanBoard' => 'https://cc-jira.rnd.ki.sw.ericsson.se/rest/api/2/search?jql=filter=%s&maxResults=1000&fields=%s',
'jira.filterFields' => [
'summary',
'priority',
'issuetype',
'labels',
'assignee',
'status',
'worklog',
'updated',
'fixVersions',
'customfield_11711', // epic link field
'customfield_11712', // epic name
'customfield_13662', // additional jiraAssignees
],
'http.proxy.enabled' => false,
'http.proxy.type' => CURLPROXY_SOCKS5,
'http.proxy.url' => "localhost:1080",
],
]; ];

3
config/routes.php Normal file → Executable file
View File

@ -46,6 +46,5 @@ return function (Application $app, MiddlewareFactory $factory, ContainerInterfac
$app->route('/api/slide[/{id:\d+}]', App\Handler\SlideHandler::class)->setName('api.slide'); $app->route('/api/slide[/{id:\d+}]', App\Handler\SlideHandler::class)->setName('api.slide');
$app->get('/avatars/{signum}', App\Handler\AvatarHandler::class,'avatar.image'); $app->get('/avatars/{signum}', App\Handler\AvatarHandler::class,'avatar.image');
$app->get('/api/kanban[/{filterId:\d+}]', App\Handler\KanbanHandler::class,'api.team.kanban'); $app->get('/api/kanban/{teamId:\d+}', App\Handler\KanbanHandler::class,'api.team.kanban');
}; };

47
src/App/Entity/KanbanEntry.php Normal file → Executable file
View File

@ -29,6 +29,12 @@ class KanbanEntry implements \JsonSerializable
*/ */
private $issueType; private $issueType;
/**
* JIRA: link to parent is in a custom field, parent has the epic name as a custom field
* @var string
*/
private $epicName;
/** /**
* @var JiraStatus * @var JiraStatus
*/ */
@ -40,7 +46,6 @@ class KanbanEntry implements \JsonSerializable
private $assignee; private $assignee;
/** /**
* JIRA: customfield_10401
* @var JiraAssignee[] * @var JiraAssignee[]
*/ */
private $additionalAssignees; private $additionalAssignees;
@ -66,68 +71,57 @@ class KanbanEntry implements \JsonSerializable
private $fixVersions; private $fixVersions;
/** /**
* JIRA: customfield_11226
* @var int * @var int
*/ */
private $prio; private $prio;
/** /**
* JIRA: customfield_11225
* @var string[]|ArrayCollection * @var string[]|ArrayCollection
*/ */
private $functionalAreas; private $functionalAreas;
/** /**
* JIRA: customfield_10010
* @var string * @var string
*/ */
private $externalId; private $externalId;
/** /**
* JIRA: customfield_10850
* @var string * @var string
*/ */
private $externalLink; private $externalLink;
/** /**
* JIRA: customfield_10840
* @var string * @var string
*/ */
private $project; private $project;
/** /**
* JIRA: customfield_10844
* @var string * @var string
*/ */
private $mhwebStatus; private $mhwebStatus;
/** /**
* JIRA: customfield_10847
* @var bool * @var bool
*/ */
private $mhwebHot; private $mhwebHot;
/** /**
* JIRA: customfield_10849
* @var bool * @var bool
*/ */
private $mhwebExternal = false; private $mhwebExternal = false;
/** /**
* JIRA: customfield_10904
* @var string * @var string
*/ */
private $team; private $team;
/** /**
* JIRA: customfield_11692
* @var string * @var string
*/ */
private $answerCode; private $answerCode;
/** /**
* ITS OVER 9000! * ITS OVER 9000!
* JIRA: customfield_12500
* @var int * @var int
*/ */
private $taurusPrio = 9001; private $taurusPrio = 9001;
@ -228,6 +222,24 @@ class KanbanEntry implements \JsonSerializable
return $this; return $this;
} }
/**
* @return string
*/
public function getEpicName(): ?string
{
return $this->epicName;
}
/**
* @param string $epicName
* @return KanbanEntry
*/
public function setEpicName(?string $epicName): KanbanEntry
{
$this->epicName = $epicName;
return $this;
}
/** /**
* @return JiraStatus * @return JiraStatus
*/ */
@ -664,22 +676,13 @@ class KanbanEntry implements \JsonSerializable
'key' => $this->getKey(), 'key' => $this->getKey(),
'summary' => $this->getSummary(), 'summary' => $this->getSummary(),
'issueType' => $this->getIssueType(), 'issueType' => $this->getIssueType(),
'epicName' => $this->getEpicName(),
'status' => $this->getStatus(), 'status' => $this->getStatus(),
'assignee' => $this->getAssignee(), 'assignee' => $this->getAssignee(),
'additionalAssignees' => $this->getAdditionalAssignees()->getValues(), 'additionalAssignees' => $this->getAdditionalAssignees()->getValues(),
'issuePriority' => $this->getIssuePriority(), 'issuePriority' => $this->getIssuePriority(),
'issuePriorityIcon' => $this->getIssuePriorityIcon(), 'issuePriorityIcon' => $this->getIssuePriorityIcon(),
'labels' => $this->getLabels(), 'labels' => $this->getLabels(),
'prio' => $this->getPrio(),
'functionalArea' => $this->getFunctionalAreas()->getValues(),
'externalId' => $this->getExternalId(),
'externalLink' => $this->getExternalLink(),
'project' => $this->getProject(),
'mhwebStatus' => $this->getMhwebStatus(),
'mhwebHot' => $this->getMhwebHot(),
'mhwebExternal' => $this->getMhwebExternal(),
'team' => $this->getTeam(),
'answerCode' => $this->getAnswerCode(),
'taurusPrio' => $this->getTaurusPrio(), 'taurusPrio' => $this->getTaurusPrio(),
'worklog' => $this->getWorklog(), 'worklog' => $this->getWorklog(),
'daysBlocked' => $this->getDaysBlocked(), 'daysBlocked' => $this->getDaysBlocked(),

153
src/App/Entity/Slide.php Normal file → Executable file
View File

@ -4,6 +4,8 @@ declare(strict_types=1);
namespace App\Entity; namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo; use Gedmo\Mapping\Annotation as Gedmo;
use JsonSerializable; use JsonSerializable;
@ -15,6 +17,12 @@ use JsonSerializable;
*/ */
class Slide implements JsonSerializable class Slide implements JsonSerializable
{ {
const TYPE_MARKDOWN = 'markdown';
const TYPE_IFRAME = 'iframe';
const VISIBILITY_PUBLIC = 'public';
const VISIBILITY_TEAM = 'team';
/** /**
* @ORM\Id * @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY") * @ORM\GeneratedValue(strategy="IDENTITY")
@ -30,18 +38,29 @@ class Slide implements JsonSerializable
private $title; private $title;
/** /**
* @ORM\ManyToOne(targetEntity="Team", inversedBy="slides") * @ORM\Column(name="type", type="string", length=50, options={"default" = "markdown"})
* @ORM\JoinColumn(name="team_id", referencedColumnName="id") * @var string
* @var Team
*/ */
private $team; private $type = self::TYPE_MARKDOWN;
/** /**
* @ORM\Column(name="slide_data", type="text", nullable=false) * @ORM\Column(name="visibility", type="string", length=50, options={"default" = "public"})
* @var string
*/
private $visibility = self::VISIBILITY_PUBLIC;
/**
* @ORM\Column(name="slide_data", type="text", nullable=true)
* @var string * @var string
*/ */
private $slideData; private $slideData;
/**
* @ORM\Column(name="slide_url", type="text", nullable=true)
* @var string
*/
private $slideUrl;
/** /**
* @ORM\Column(name="is_visible", type="boolean") * @ORM\Column(name="is_visible", type="boolean")
* @var bool * @var bool
@ -69,6 +88,17 @@ class Slide implements JsonSerializable
*/ */
private $position; private $position;
/**
* @ORM\ManyToMany(targetEntity="Team", inversedBy="slides", cascade={"persist", "remove"})
* @var Team[]|ArrayCollection
*/
private $teams;
public function __construct()
{
$this->teams = new ArrayCollection();
}
/** /**
* @return int * @return int
*/ */
@ -106,20 +136,38 @@ class Slide implements JsonSerializable
} }
/** /**
* @return Team * @return string
*/ */
public function getTeam(): ?Team public function getType(): ?string
{ {
return $this->team; return $this->type;
} }
/** /**
* @param Team $team * @param string $type
* @return Slide * @return Slide
*/ */
public function setTeam(?Team $team): Slide public function setType(?string $type): Slide
{ {
$this->team = $team; $this->type = $type;
return $this;
}
/**
* @return string
*/
public function getVisibility(): ?string
{
return $this->visibility;
}
/**
* @param string $visibility
* @return Slide
*/
public function setVisibility(?string $visibility): Slide
{
$this->visibility = $visibility;
return $this; return $this;
} }
@ -135,12 +183,30 @@ class Slide implements JsonSerializable
* @param string $slideData * @param string $slideData
* @return Slide * @return Slide
*/ */
public function setSlideData(string $slideData): Slide public function setSlideData(?string $slideData): Slide
{ {
$this->slideData = $slideData; $this->slideData = $slideData;
return $this; return $this;
} }
/**
* @return string
*/
public function getSlideUrl(): ?string
{
return $this->slideUrl;
}
/**
* @param string $slideUrl
* @return Slide
*/
public function setSlideUrl(?string $slideUrl): Slide
{
$this->slideUrl = $slideUrl;
return $this;
}
/** /**
* @return bool * @return bool
*/ */
@ -213,6 +279,64 @@ class Slide implements JsonSerializable
return $this; return $this;
} }
/**
* @param Team $team
* @return Slide
*/
public function addTeam(Team $team): Slide
{
if (!$this->teams->contains($team)) {
$this->teams->add($team);
}
//$team->addSlide($this);
return $this;
}
/**
* @param Team[] $teams
* @return Slide
*/
public function addTeams($teams): Slide
{
foreach ($teams as $team) {
$this->addTeam($team);
}
return $this;
}
/**
* @return Team[]|Collection
*/
public function getTeams(): Collection
{
return $this->teams;
}
/**
* @param Team $team
* @return Slide
*/
public function removeTeam(Team $team): Slide
{
if ($this->teams->contains($team)) {
$this->teams->removeElement($team);
}
//$team->removeSlide($this);
return $this;
}
/**
* @param Team[] $teams
* @return Slide
*/
public function removeTeams($teams): Slide
{
foreach ($teams as $team) {
$this->removeTeam($team);
}
return $this;
}
/** /**
* @return array * @return array
*/ */
@ -221,8 +345,11 @@ class Slide implements JsonSerializable
return [ return [
'id' => $this->getId(), 'id' => $this->getId(),
'title' => $this->getTitle(), 'title' => $this->getTitle(),
'team' => $this->getTeam(), 'type' => $this->getType(),
'visibility' => $this->getVisibility(),
'teams' => $this->getTeams()->getValues(),
'slideData' => $this->getSlideData(), 'slideData' => $this->getSlideData(),
'slideUrl' => $this->getSlideUrl(),
'isVisible' => $this->isVisible(), 'isVisible' => $this->isVisible(),
'createdAt' => $this->getCreatedAt() 'createdAt' => $this->getCreatedAt()
? $this->getCreatedAt()->format("Y-m-d H:i:s") ? $this->getCreatedAt()->format("Y-m-d H:i:s")

18
src/App/Entity/Team.php Normal file → Executable file
View File

@ -37,11 +37,15 @@ class Team implements JsonSerializable
private $members; private $members;
/** /**
* @ORM\OneToMany( * @ORM\ManyToMany(targetEntity="Slide", mappedBy="teams", cascade={"persist", "remove"})
* targetEntity="Slide", * @ORM\JoinTable(
* mappedBy="team", * name="team_slides",
* cascade={"persist", "remove"}, * joinColumns={
* orphanRemoval=true * @ORM\JoinColumn(name="team_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="slide_id", referencedColumnName="id")
* }
* ) * )
* @var Slide[]|Collection * @var Slide[]|Collection
*/ */
@ -166,11 +170,12 @@ class Team implements JsonSerializable
* @param Slide $slide * @param Slide $slide
* @return Team * @return Team
*/ */
public function addSlides(Slide $slide): Team public function addSlide(Slide $slide): Team
{ {
if (!$this->slides->contains($slide)) { if (!$this->slides->contains($slide)) {
$this->slides->removeElement($slide); $this->slides->removeElement($slide);
} }
//$slide->addTeam($this);
return $this; return $this;
} }
@ -191,6 +196,7 @@ class Team implements JsonSerializable
if ($this->slides->contains($slide)) { if ($this->slides->contains($slide)) {
$this->slides->removeElement($slide); $this->slides->removeElement($slide);
} }
//$slide->removeTeam($this);
return $this; return $this;
} }

53
src/App/Form/Slide.php Normal file → Executable file
View File

@ -30,9 +30,34 @@ class Slide
*/ */
private $title; private $title;
/**
* @Annotation\Type("Zend\Form\Element\Text")
* @Annotation\Required(true)
* @Annotation\InputFilter("Zend\Filter\StringTrim")
* @Annotation\Options({
* "label": "Slide type"
* })
* @var string
*/
private $type;
/**
* @Annotation\Type("Zend\Form\Element\Text")
* @Annotation\Required(true)
* @Annotation\InputFilter("Zend\Filter\StringTrim")
* @Annotation\Options({
* "label": "Slide visibility"
* })
* @var string
*/
private $visibility;
/** /**
* @Annotation\Type("doctrine.object_select") * @Annotation\Type("doctrine.object_select")
* @Annotation\Required(false) * @Annotation\Required(false)
* @Annotation\Attributes({
* "multiple": true
* })
* @Annotation\Options({ * @Annotation\Options({
* "property": "name", * "property": "name",
* "label": "Team", * "label": "Team",
@ -48,21 +73,39 @@ class Slide
* } * }
* } * }
* }) * })
* @var * @var Team[]
*/ */
private $team; private $teams;
/** /**
* @Annotation\Type("Zend\Form\Element\Text") * @Annotation\Type("Zend\Form\Element\Text")
* @Annotation\Required(true) * @Annotation\Required(false)
* @Annotation\InputFilter("Zend\Filter\StringTrim") * @Annotation\InputFilter("Zend\Filter\StringTrim")
* @Annotation\Options({ * @Annotation\Options({
* "label": "Slide contents" * "label": "Slide contents (type markdown)"
* }) * })
* @var * @var string
*/ */
private $slideData; private $slideData;
/**
* @Annotation\Type("Zend\Form\Element\Text")
* @Annotation\Required(false)
* @Annotation\InputFilter("Zend\Filter\StringTrim")
* @Annotation\Options({
* "label": "Slide url (type iframe)"
* })
* @Annotation\Validator({
* "name":"Uri",
* "options": {
* "allowAbsolute": true,
* "allowRelative": false,
* }
* })
* @var string
*/
private $slideUrl;
/** /**
* @Annotation\Type("Zend\Form\Element\Checkbox") * @Annotation\Type("Zend\Form\Element\Checkbox")
* @Annotation\Options({ * @Annotation\Options({

4
src/App/Handler/KanbanHandler.php Normal file → Executable file
View File

@ -32,9 +32,9 @@ class KanbanHandler implements RequestHandlerInterface
*/ */
public function handle(ServerRequestInterface $request): ResponseInterface public function handle(ServerRequestInterface $request): ResponseInterface
{ {
$filterId = $request->getAttribute('filterId'); $teamId = (int)$request->getAttribute('teamId');
/** @var KanbanBoard $kanbanResult */ /** @var KanbanBoard $kanbanResult */
$kanbanResult = $this->dataCollector->getKanbanBoard($filterId); $kanbanResult = $this->dataCollector->getKanbanBoard($teamId);
return new JsonResponse($kanbanResult); return new JsonResponse($kanbanResult);
} }
} }

177
src/App/Service/JiraCollectorService.php Normal file → Executable file
View File

@ -9,6 +9,7 @@ use App\Entity\JiraIssueType;
use App\Entity\JiraStatus; use App\Entity\JiraStatus;
use App\Entity\KanbanBoard; use App\Entity\KanbanBoard;
use App\Entity\KanbanEntry; use App\Entity\KanbanEntry;
use App\Entity\Team;
use Zend\Cache\Storage\StorageInterface; use Zend\Cache\Storage\StorageInterface;
use Zend\Config\Config; use Zend\Config\Config;
use Zend\Expressive\Router\RouterInterface; use Zend\Expressive\Router\RouterInterface;
@ -20,6 +21,10 @@ class JiraCollectorService
{ {
const CACHE_KEY_KANBANBOARD = 'kanbanBoard'; const CACHE_KEY_KANBANBOARD = 'kanbanBoard';
const BACKLOG_FIELD_DELIMITER = ';';
const EPIC_TICKET_LINK = 'customfield_11711';
const EPIC_NAME_FIELD = 'customfield_11712';
/** @var StorageInterface */ /** @var StorageInterface */
private $cache; private $cache;
@ -33,39 +38,54 @@ class JiraCollectorService
/** @var RouterInterface */ /** @var RouterInterface */
private $router; private $router;
/** @var TeamService */
private $teamService;
/** @var array */
private $cachedEpics = [];
/** /**
* JiraClientService constructor. * JiraClientService constructor.
* @param StorageInterface $cache * @param StorageInterface $cache
* @param Client $client * @param Client $client
* @param Config $config * @param Config $config
* @param RouterInterface $router * @param RouterInterface $router
* @param TeamService $teamService
*/ */
public function __construct(StorageInterface $cache, Client $client, Config $config, RouterInterface $router) public function __construct(StorageInterface $cache,
Client $client,
Config $config,
RouterInterface $router,
TeamService $teamService)
{ {
$this->cache = $cache; $this->cache = $cache;
$this->router = $router; $this->router = $router;
$this->httpClient = $client; $this->httpClient = $client;
$this->config = $config; $this->config = $config;
$this->teamService = $teamService;
} }
/** /**
* @param int $filterId * @param int $teamId
* @param bool $forceReload * @param bool $forceReload
* @return KanbanBoard * @return KanbanBoard
*/ */
public function getKanbanBoard(int $filterId = null, bool $forceReload = false): KanbanBoard public function getKanbanBoard(int $teamId = null, bool $forceReload = false): KanbanBoard
{ {
$kanbanBoard = $this->cache->getItem('kanbanBoard'); $team = $this->teamService->getTeam($teamId);
$teamName = $team->getName();
$kanbanBoard = $this->cache->getItem(sprintf("%s-%s", self::CACHE_KEY_KANBANBOARD, $teamName));
if ($forceReload || null === $kanbanBoard) { if ($forceReload || null === $kanbanBoard) {
$user = $this->config->get('jira.user'); $user = $this->config->get('jira.user');
$password = $this->config->get('jira.password'); $password = $this->config->get('jira.password');
/** @var Config $kanbanBoardUriParams */ /** @var Config $kanbanBoardUriParams */
$kanbanBoardUriParams = $this->config->get('url.jiraKanbanBoard'); $kanbanBoardUri = $this->config->get('url.jiraKanbanBoard');
$kanbanBoardFilter = $this->config->get('jira.filterFields')->toArray();
$kanbanBoardUri = sprintf( $kanbanBoardUri = sprintf(
$kanbanBoardUriParams['baseUrl'], $kanbanBoardUri,
isset($filterId) ? $filterId : $kanbanBoardUriParams['filterId'], $team->getFilterId(),
implode(",", $kanbanBoardUriParams['fields']->toArray()) implode(",", $kanbanBoardFilter)
); );
$response = $this->httpClient $response = $this->httpClient
@ -79,8 +99,8 @@ class JiraCollectorService
$parsedJsonData = Decoder::decode($response->getBody(), Json::TYPE_ARRAY); $parsedJsonData = Decoder::decode($response->getBody(), Json::TYPE_ARRAY);
$kanbanBoard = $this->hydrateKanbanBoard($parsedJsonData); $kanbanBoard = $this->hydrateKanbanBoard($team, $parsedJsonData);
$this->cache->setItem(self::CACHE_KEY_KANBANBOARD, serialize($kanbanBoard)); $this->cache->setItem(sprintf("%s-%s", self::CACHE_KEY_KANBANBOARD, $teamName), serialize($kanbanBoard));
} else { } else {
$kanbanBoard = unserialize($kanbanBoard); $kanbanBoard = unserialize($kanbanBoard);
} }
@ -89,22 +109,77 @@ class JiraCollectorService
} }
/** /**
* @param string $parentKey
* @return null|string
*/
private function getEpicNameFromParent(string $parentKey): ?string
{
if (array_key_exists($parentKey, $this->cachedEpics)) {
return $this->cachedEpics[$parentKey];
}
$user = $this->config->get('jira.user');
$password = $this->config->get('jira.password');
/** @var Config $kanbanBoardUriParams */
$jiraIssueBaseUrl = $this->config->get('url.jiraIssue');
$kanbanBoardFilter = $this->config->get('jira.filterFields')->toArray();
$kanbanBoardFilterString = implode(",", $kanbanBoardFilter);
$jiraIssueUri = sprintf($jiraIssueBaseUrl, $parentKey, $kanbanBoardFilterString);
$response = $this->httpClient
->setUri($jiraIssueUri)
->setAuth($user, $password)
->send();
if (!$response->isSuccess()) {
throw new \UnexpectedValueException("Bad JIRA result: $jiraIssueUri", $response->getStatusCode());
}
$parsedJsonParentData = Decoder::decode($response->getBody(), Json::TYPE_ARRAY);
if ($parsedJsonParentData['fields'][self::EPIC_TICKET_LINK]) {
$jiraIssueUri = sprintf(
$jiraIssueBaseUrl,
$parsedJsonParentData['fields'][self::EPIC_TICKET_LINK],
$kanbanBoardFilterString
);
$response = $this->httpClient
->setUri($jiraIssueUri)
->setAuth($user, $password)
->send();
if (!$response->isSuccess()) {
throw new \UnexpectedValueException("Bad JIRA result", $response->getStatusCode());
}
$parsedJsonEpicData = Decoder::decode($response->getBody(), Json::TYPE_ARRAY);
$this->cachedEpics[$parentKey] = $parsedJsonEpicData['fields'][self::EPIC_NAME_FIELD];
return $this->cachedEpics[$parentKey];
}
$this->cachedEpics[$parentKey] = null;
return null;
}
/**
* @param Team $team
* @param $parsedJsonData * @param $parsedJsonData
* @return KanbanBoard * @return KanbanBoard
* @todo check if avatar has to be locally cached * @todo check if avatar has to be locally cached
*/ */
private function hydrateKanbanBoard($parsedJsonData): KanbanBoard private function hydrateKanbanBoard(Team $team, $parsedJsonData): KanbanBoard
{ {
$kanbanBoard = new KanbanBoard(); $kanbanBoard = new KanbanBoard();
$teamBacklogColumns = explode(self::BACKLOG_FIELD_DELIMITER, $team->getBacklogColumn()["jiraStatusName"]);
$teamInprogressColumns = explode(self::BACKLOG_FIELD_DELIMITER, $team->getInprogressColumn()["jiraStatusName"]);
$teamVerificationColumns = explode(self::BACKLOG_FIELD_DELIMITER, $team->getVerificationColumn()["jiraStatusName"]);
$teamDoneColumns = explode(self::BACKLOG_FIELD_DELIMITER, $team->getDoneColumn()["jiraStatusName"]);
foreach ($parsedJsonData['issues'] as $jsonIssue) { foreach ($parsedJsonData['issues'] as $jsonIssue) {
set_time_limit(30);
$kanbanEntry = new KanbanEntry(); $kanbanEntry = new KanbanEntry();
$kanbanEntry->setId(intval($jsonIssue['id'])) $kanbanEntry->setId(intval($jsonIssue['id']))
->setKey($jsonIssue['key']) ->setKey($jsonIssue['key'])
->setSummary($jsonIssue['fields']['summary']) ->setSummary($jsonIssue['fields']['summary'])
->setExternalLink($jsonIssue['fields']['customfield_10850'])
->setMhwebStatus($jsonIssue['fields']['customfield_10844'])
->setAnswerCode($jsonIssue['fields']['customfield_11692'])
->setIssuePriority($jsonIssue['fields']['priority']['name']) ->setIssuePriority($jsonIssue['fields']['priority']['name'])
->setIssuePriorityIcon($jsonIssue['fields']['priority']['iconUrl']) ->setIssuePriorityIcon($jsonIssue['fields']['priority']['iconUrl'])
->setLabels($jsonIssue['fields']['labels']) ->setLabels($jsonIssue['fields']['labels'])
@ -143,48 +218,13 @@ class JiraCollectorService
} }
} }
// externalId : customfield_10010 // epicName: have to fetch 2 extra records
if (isset($jsonIssue['fields']['customfield_10010'])) { if (isset($jsonIssue['fields'][self::EPIC_TICKET_LINK])) {
$kanbanEntry->setExternalId($jsonIssue['fields']['customfield_10010']); $epicName = $this->getEpicNameFromParent($jsonIssue['key']);
} $kanbanEntry->setEpicName($epicName);
} elseif (isset($jsonIssue['fields']['parent'])) {
// prio : customfield_10840 $epicName = $this->getEpicNameFromParent($jsonIssue['fields']['parent']['key']);
if (isset($jsonIssue['fields']['customfield_11226'])) { $kanbanEntry->setEpicName($epicName);
$kanbanEntry->setPrio($jsonIssue['fields']['customfield_11226']);
}
// functional area : customfield_11225
if (isset($jsonIssue['fields']['customfield_11225'])) {
foreach ($jsonIssue['fields']['customfield_11225'] as $functionalArea) {
$kanbanEntry->addFunctionalArea($functionalArea['value']);
}
}
// project : customfield_10840
if (isset($jsonIssue['fields']['customfield_10840'])) {
$kanbanEntry->setProject($jsonIssue['fields']['customfield_10840']['value']);
}
// mhweb hot : customfield_10847
if (isset($jsonIssue['fields']['customfield_10847'])) {
$boolVal = $jsonIssue['fields']['customfield_10847'][0]['value'] == 'yes';
$kanbanEntry->setMhwebHot($boolVal);
}
// mhweb external : customfield_10849
if (isset($jsonIssue['fields']['customfield_10849'])) {
$boolVal = $jsonIssue['fields']['customfield_10849'][0]['value'] == 'yes';
$kanbanEntry->setMhwebExternal($boolVal);
}
// team : customfield_10904
if (isset($jsonIssue['fields']['customfield_10904'])) {
$kanbanEntry->setTeam($jsonIssue['fields']['customfield_10904']['value']);
}
// team : customfield_12500
if (isset($jsonIssue['fields']['customfield_12500'])) {
$kanbanEntry->setTaurusPrio($jsonIssue['fields']['customfield_12500']);
} }
// jira status // jira status
@ -222,20 +262,17 @@ class JiraCollectorService
} }
$kanbanEntry->setUpdatedAt(new \DateTime($jsonIssue['fields']['updated'])); $kanbanEntry->setUpdatedAt(new \DateTime($jsonIssue['fields']['updated']));
if (in_array($jiraStatus->getName(), $teamBacklogColumns)) {
switch ($jiraStatus->getName()) { $kanbanBoard->addInbox($kanbanEntry);
case "Backlog": }
$kanbanBoard->addInbox($kanbanEntry); elseif (in_array($jiraStatus->getName(), $teamInprogressColumns)) {
break; $kanbanBoard->addInProgress($kanbanEntry);
case "In Progress": }
$kanbanBoard->addInProgress($kanbanEntry); elseif (in_array($jiraStatus->getName(), $teamVerificationColumns)) {
break; $kanbanBoard->addVerification($kanbanEntry);
case "Verification": }
$kanbanBoard->addVerification($kanbanEntry); elseif (in_array($jiraStatus->getName(), $teamDoneColumns)) {
break; $kanbanBoard->addDone($kanbanEntry);
case "Done":
$kanbanBoard->addDone($kanbanEntry);
break;
} }
unset($kanbanEntry); unset($kanbanEntry);
} }

3
src/App/Service/JiraCollectorServiceFactory.php Normal file → Executable file
View File

@ -18,6 +18,7 @@ class JiraCollectorServiceFactory
$httpClient = $container->get(Client::class); $httpClient = $container->get(Client::class);
$config = new Config($configArray['app.config']); $config = new Config($configArray['app.config']);
$router = $container->get(RouterInterface::class); $router = $container->get(RouterInterface::class);
return new JiraCollectorService($cache,$httpClient, $config, $router); $teamService = $container->get(TeamService::class);
return new JiraCollectorService($cache,$httpClient, $config, $router, $teamService);
} }
} }

0
src/App/Service/SlideManager.php Normal file → Executable file
View File