feat: extend job-profile and feedback entities for future statistics
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20251216135542 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE feedback ADD assignment_id INT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE feedback ADD CONSTRAINT FK_D2294458D19302F8 FOREIGN KEY (assignment_id) REFERENCES assignment (id)');
|
||||
$this->addSql('CREATE INDEX IDX_D2294458D19302F8 ON feedback (assignment_id)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE feedback DROP FOREIGN KEY FK_D2294458D19302F8');
|
||||
$this->addSql('DROP INDEX IDX_D2294458D19302F8 ON feedback');
|
||||
$this->addSql('ALTER TABLE feedback DROP assignment_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20251216162601 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE feedback ADD job_profile_category VARCHAR(32) DEFAULT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE feedback DROP job_profile_category');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20251218100000 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Split course category into course_ski/course_board and add event_team category based on job profile names';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// Split course category: profiles with "Ski" in name become course_ski
|
||||
$this->addSql("
|
||||
UPDATE job_profile
|
||||
SET category = 'course_ski'
|
||||
WHERE category = 'course'
|
||||
AND name LIKE '%Ski%'
|
||||
");
|
||||
|
||||
// Split course category: profiles with "Board" or "Snowboard" in name become course_board
|
||||
$this->addSql("
|
||||
UPDATE job_profile
|
||||
SET category = 'course_board'
|
||||
WHERE category = 'course'
|
||||
AND (name LIKE '%Board%' OR name LIKE '%Snowboard%')
|
||||
");
|
||||
|
||||
// New event_team category for profiles containing "Event" in name
|
||||
$this->addSql("
|
||||
UPDATE job_profile
|
||||
SET category = 'event_team'
|
||||
WHERE name LIKE '%Event%'
|
||||
");
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// Revert course_ski and course_board back to course
|
||||
$this->addSql("
|
||||
UPDATE job_profile
|
||||
SET category = 'course'
|
||||
WHERE category IN ('course_ski', 'course_board')
|
||||
");
|
||||
|
||||
// Note: Cannot reliably revert event_team as we don't know original category
|
||||
$this->addSql("
|
||||
UPDATE job_profile
|
||||
SET category = 'service'
|
||||
WHERE category = 'event_team'
|
||||
");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20251218100001 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Backfill assignment_id and job_profile_category on feedback table from existing disposition data';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// Backfill assignment_id from disposition's feedback relation
|
||||
$this->addSql('
|
||||
UPDATE feedback f
|
||||
INNER JOIN disposition d ON d.feedback_id = f.id
|
||||
SET f.assignment_id = d.assignment_id
|
||||
WHERE f.assignment_id IS NULL
|
||||
');
|
||||
|
||||
// Backfill job_profile_category from assignment's job profile
|
||||
$this->addSql('
|
||||
UPDATE feedback f
|
||||
INNER JOIN assignment a ON a.id = f.assignment_id
|
||||
INNER JOIN job_profile jp ON jp.id = a.job_profile_id
|
||||
SET f.job_profile_category = jp.category
|
||||
WHERE f.job_profile_category IS NULL
|
||||
AND f.assignment_id IS NOT NULL
|
||||
');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// Data migration - setting to NULL on rollback
|
||||
$this->addSql('UPDATE feedback SET assignment_id = NULL, job_profile_category = NULL');
|
||||
}
|
||||
}
|
||||
@@ -91,6 +91,9 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
|
||||
#[ORM\ManyToMany(targetEntity: Teamer::class, mappedBy: 'bookmarks')]
|
||||
private Collection $teamers;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'assignment', targetEntity: Feedback::class)]
|
||||
private Collection $feedback;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
private ?User $owner = null;
|
||||
|
||||
@@ -109,6 +112,7 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
|
||||
$this->applications = new ArrayCollection();
|
||||
$this->dispositions = new ArrayCollection();
|
||||
$this->teamers = new ArrayCollection();
|
||||
$this->feedback = new ArrayCollection();
|
||||
$this->benefits = "Anreise im E&P Reisebus\nUnterkunft\nVerpflegung\nSkipass\n";
|
||||
}
|
||||
|
||||
@@ -537,6 +541,30 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, Feedback#>
|
||||
*/
|
||||
public function getFeedback(): Collection
|
||||
{
|
||||
return $this->feedback;
|
||||
}
|
||||
|
||||
public function addFeedback(Feedback $feedback): static
|
||||
{
|
||||
if (!$this->feedback->contains($feedback)) {
|
||||
$this->feedback->add($feedback);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeFeedback(Feedback $feedback): static
|
||||
{
|
||||
$this->feedback->removeElement($feedback);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOwner(): ?User
|
||||
{
|
||||
return $this->owner;
|
||||
|
||||
@@ -35,12 +35,18 @@ class Feedback implements BlameableEntityInterface, TimestampableEntityInterface
|
||||
#[Assert\NotNull(message: 'Bitte auswählen', groups: ['admin'])]
|
||||
private ?Teamer $teamer = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'feedback')]
|
||||
private ?Assignment $assignment = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $destinationName = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $jobProfileName = null;
|
||||
|
||||
#[ORM\Column(length: 32, nullable: true)]
|
||||
private ?string $jobProfileCategory = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $hotel = null;
|
||||
|
||||
@@ -90,6 +96,7 @@ class Feedback implements BlameableEntityInterface, TimestampableEntityInterface
|
||||
$jobProfile = $assignment->getJobProfile();
|
||||
|
||||
$instance
|
||||
->setAssignment($assignment)
|
||||
->setAssignmentDateFrom($assignment->getEffectiveDateFrom())
|
||||
->setAssignmentDateTo($assignment->getEffectiveDateTo())
|
||||
->setDestinationName($destination->getProduct())
|
||||
@@ -97,6 +104,7 @@ class Feedback implements BlameableEntityInterface, TimestampableEntityInterface
|
||||
->setHotelCode($destination->getHotelCode())
|
||||
->setHotelBusProId($destination->getHotelBusProId())
|
||||
->setJobProfileName($jobProfile->getName())
|
||||
->setJobProfileCategory($jobProfile->getCategory())
|
||||
;
|
||||
|
||||
return $instance;
|
||||
@@ -124,6 +132,18 @@ class Feedback implements BlameableEntityInterface, TimestampableEntityInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAssignment(): ?Assignment
|
||||
{
|
||||
return $this->assignment;
|
||||
}
|
||||
|
||||
public function setAssignment(?Assignment $assignment): static
|
||||
{
|
||||
$this->assignment = $assignment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTeamer(): ?Teamer
|
||||
{
|
||||
return $this->teamer;
|
||||
@@ -184,6 +204,18 @@ class Feedback implements BlameableEntityInterface, TimestampableEntityInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getJobProfileCategory(): ?string
|
||||
{
|
||||
return $this->jobProfileCategory;
|
||||
}
|
||||
|
||||
public function setJobProfileCategory(?string $jobProfileCategory): static
|
||||
{
|
||||
$this->jobProfileCategory = $jobProfileCategory;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHotel(): ?string
|
||||
{
|
||||
return $this->hotel;
|
||||
|
||||
@@ -22,7 +22,10 @@ class JobProfile implements BlameableEntityInterface, TimestampableEntityInterfa
|
||||
|
||||
public const CATEGORY_GUIDE = 'guide';
|
||||
public const CATEGORY_COURSE = 'course';
|
||||
public const CATEGORY_COURSE_SKI = 'course_ski';
|
||||
public const CATEGORY_COURSE_BOARD = 'course_board';
|
||||
public const CATEGORY_SERVICE = 'service';
|
||||
public const CATEGORY_EVENT_TEAM = 'event_team';
|
||||
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
@@ -99,7 +102,10 @@ class JobProfile implements BlameableEntityInterface, TimestampableEntityInterfa
|
||||
return match ($this->category) {
|
||||
static::CATEGORY_GUIDE => 'Reiseleitung',
|
||||
static::CATEGORY_COURSE => 'Kursleitung',
|
||||
static::CATEGORY_COURSE_SKI => 'Kursleitung Ski',
|
||||
static::CATEGORY_COURSE_BOARD => 'Kursleitung Board',
|
||||
static::CATEGORY_SERVICE => 'Serviceteam',
|
||||
static::CATEGORY_EVENT_TEAM => 'Eventteam',
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -27,8 +27,10 @@ class JobProfileType extends AbstractType
|
||||
'placeholder' => 'bitte zuordnen...',
|
||||
'choices' => [
|
||||
'Reiseleitung' => JobProfile::CATEGORY_GUIDE,
|
||||
'Kursleitung' => JobProfile::CATEGORY_COURSE,
|
||||
'Kursleitung Ski' => JobProfile::CATEGORY_COURSE_SKI,
|
||||
'Kursleitung Board' => JobProfile::CATEGORY_COURSE_BOARD,
|
||||
'Serviceteam' => JobProfile::CATEGORY_SERVICE,
|
||||
'Eventteam' => JobProfile::CATEGORY_EVENT_TEAM,
|
||||
],
|
||||
])
|
||||
->add('requiredTrainings', EntityType::class, [
|
||||
|
||||
Reference in New Issue
Block a user