Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clearly show vacancies for officerships with multiple people #1103

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ services:
POSTGRES_PASSWORD: myradio
volumes:
- db-data:/var/lib/postgresql/data
ports:
- 55432:5432

memcached:
image: memcached:alpine
Expand Down
6 changes: 6 additions & 0 deletions schema/patches/16.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
BEGIN;

ALTER TABLE public.officer
ADD COLUMN num_places INT DEFAULT 1;

COMMIT;
2 changes: 1 addition & 1 deletion src/Classes/MyRadioTwig.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public function __construct()
* @param string $name The name of the variable
* @param mixed $value The value of the variable - literally any valid type
*
* @return \MyRadioTwig This for chaining
* @return MyRadioTwig This for chaining
*/
public function addVariable($name, $value)
{
Expand Down
56 changes: 46 additions & 10 deletions src/Classes/ServiceAPI/MyRadio_Officer.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ class MyRadio_Officer extends ServiceAPI
*/
private $permissions;

/**
* How many people can have this officership - should be 1 for most.
* @var int
*/
private $num_places;

protected function __construct($id)
{
$result = self::$db->fetchOne(
Expand All @@ -101,6 +107,7 @@ protected function __construct($id)
$this->description = $result['descr'];
$this->status = $result['status'];
$this->type = $result['type'];
$this->num_places = (int) $result['num_places'];

//Get the officer's permissions
$this->updatePermissions();
Expand All @@ -110,23 +117,24 @@ protected function __construct($id)
/**
* Create a new Officer position.
*
* @param string $name The position name, e.g. "Station Cat"
* @param string $descr A description of the position "official feline"
* @param string $alias Email alias (may be NULL) e.g. station.cat
* @param int $ordering Weighting when appearing in lists e.g. 0
* @param MyRadio_Team $team The Team the Officer is part of
* @param char $type 'm'ember, 'o'fficer, 'a'ssistant head, 'h'ead
* @param string $name The position name, e.g. "Station Cat"
* @param string $descr A description of the position "official feline"
* @param string $alias Email alias (may be NULL) e.g. station.cat
* @param int $ordering Weighting when appearing in lists e.g. 0
* @param MyRadio_Team $team The Team the Officer is part of
* @param char $type 'm'ember, 'o'fficer, 'a'ssistant head, 'h'ead
* @param int $num_places How many people can have this officership (default 1)
*
* @return MyRadio_Officer The new Officer position
*/
public static function createOfficer($name, $descr, $alias, $ordering, MyRadio_Team $team, $type = 'o')
public static function createOfficer($name, $descr, $alias, $ordering, MyRadio_Team $team, $type = 'o', $num_places = 1)
{
return self::getInstance(
self::$db->fetchColumn(
'INSERT INTO public.officer
(officer_name, officer_alias, teamid, ordering, descr, type)
VALUES ($1, $2, $3, $4, $5, $6) RETURNING officerid',
[$name, $alias, $team->getID(), $ordering, $descr, $type]
(officer_name, officer_alias, teamid, ordering, descr, type, num_places)
VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING officerid',
[$name, $alias, $team->getID(), $ordering, $descr, $type, $num_places]
)[0]
);
}
Expand Down Expand Up @@ -543,6 +551,22 @@ private function considerEmailingNewOfficer(MyRadio_User $member)
);
}

public function getNumPlaces()
{
return $this->num_places;
}

public function setNumPlaces(int $val)
{
self::$db->query('
UPDATE public.officer
SET num_places = $1
WHERE officerid = $2
', [$val, $this->getID()]);
$this->num_places = $val;
$this->updateCacheObject();
}

/**
* Returns all the officer's active permission flags.
*
Expand Down Expand Up @@ -659,6 +683,16 @@ public static function getForm()
'required' => false,
]
)
)->addField(
new MyRadioFormField(
'num_places',
MyRadioFormField::TYPE_NUMBER,
[
'label' => 'Number of Places',
'explanation' => 'How many people can have this officership at a time.',
'value' => 1,
]
)
)->addField(
new MyRadioFormField(
'status',
Expand Down Expand Up @@ -759,6 +793,7 @@ public function getEditForm()
'team' => $this->getTeam()->getID(),
'type' => $this->getType(),
'status' => $this->getStatus(),
'num_places' => $this->getNumPlaces(),
'permissions.permission' => array_map(
function ($perm) {
return $perm['value'];
Expand Down Expand Up @@ -828,6 +863,7 @@ public function toDataSource($mixins = [])
'description' => $this->getDescription(),
'status' => $this->getStatus(),
'type' => $this->getType(),
'num_places' => $this->getNumPlaces(),
];

$this->addMixins($data, $mixins, $mixin_funcs);
Expand Down
37 changes: 36 additions & 1 deletion src/Classes/ServiceAPI/Profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public static function getOfficers()
if (self::$officers === false) {
self::wakeup();
self::$officers = self::$db->fetchAll(
'SELECT team.team_name AS team, officer.type, officer.officer_name AS officership,
'SELECT team.team_name AS team, officer.type, officer.officer_name AS officership, officer.num_places,
fname || \' \' || sname AS name, member.memberid, officer.officerid
FROM team
LEFT JOIN officer ON team.teamid = officer.teamid AND officer.status = \'c\'
Expand All @@ -145,8 +145,43 @@ public static function getOfficers()
WHERE team.status = \'c\' AND officer.type != \'m\'
ORDER BY team.ordering, officer.ordering, sname'
);
// Insert into the list duplicate entries for vacant positions
// For example, if ASM has num_positions=2, and only one is filled,
// we need to insert another ASM entry with null name/memberid

// keyed by officerid
$num_filled_positions = [];
// dto - avoid iterating multiple times
$num_avail_positions = [];
$last_index_of_officer = [];
foreach (self::$officers as $i => $off) {
$num_avail_positions[$off['officerid']] = (int)$off['num_places'];
if ($off['memberid'] !== null) {
$num_filled_positions[$off['officerid']]++;
}
$last_index_of_officer[$off['officerid']] = $i;
}

$offset = 0;
foreach ($num_avail_positions as $officerid => $avail) {
if ($num_filled_positions[$officerid] < $avail && $avail > 1) {
$vacancies = ($avail ?? 1) - $num_filled_positions[$officerid];
if ($num_filled_positions[$officerid] == 0) {
$vacancies--;
}
for ($i = 0; $i < $vacancies; $i++) {
$vacancy = self::$officers[$last_index_of_officer[$officerid]+$offset];
$vacancy['memberid'] = null;
$vacancy['name'] = null;
array_splice(self::$officers, $last_index_of_officer[$officerid]+$offset+1, 0, [$vacancy]);
$offset++;
}
}
}

self::$cache->set('MyRadioProfile_officers', self::$officers);
}
// var_dump(self::$officers);

return self::$officers;
}
Expand Down
6 changes: 4 additions & 2 deletions src/Controllers/Profile/editOfficer.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
$data['alias'],
$data['ordering'],
$data['team'],
$data['type']
$data['type'],
(int) $data['num_places']
);
} else {
//submit edit
Expand All @@ -31,7 +32,8 @@
->setOrdering($data['ordering'])
->setTeam($data['team'])
->setType($data['type'])
->setStatus($data['status']);
->setStatus($data['status'])
->setNumPlaces((int) $data['num_places']);

// remove empty permissions values
$data['permissions'] = array_filter($data['permissions']['permission']) ?: [];
Expand Down
4 changes: 4 additions & 0 deletions src/Public/js/myradio.profile.listOfficers.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ $(".twig-datatable").dataTable({
{
"sTitle": "Officership",
},
// numPlaces
{
bVisible: false
},
//name
{
"sTitle": "Name"
Expand Down