packages feed

weekdaze-0.0.0.1: src-lib/WeekDaze/Data/HumanResource.hs

{-
	Copyright (C) 2013-2015 Dr. Alistair Ward

	This file is part of WeekDaze.

	WeekDaze is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	WeekDaze is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with WeekDaze.  If not, see <http://www.gnu.org/licenses/>.
-}
{- |
 [@AUTHOR@]	Dr. Alistair Ward

 [@DESCRIPTION@]

	* Describes an aspect of either a /teacher/ or /student/.

	* These /resource/s have a requirement to devote a portion of their week to teaching,
	whereas a /location/ doesn't care what it's being used for.

	* They can also be members of heterogenous groups of other /human-resources/.
-}

module WeekDaze.Data.HumanResource(
-- * Type-classes
	HumanResource(..),
-- * Constants
	groupMembershipTag,
	defaultGroupMembership,
-- * Functions
	calculateNTimeslotsPerWeekAvailable,
	extractDistinctGroupMembership,
	extractGroupMembersOf,
	extractCombinedGroupMembership,
-- ** Predicates
	hasFreePeriodPreference
) where

import qualified	Data.Map
import qualified	Data.Maybe
import qualified	Data.Set
import qualified	WeekDaze.Data.Group			as Data.Group
import qualified	WeekDaze.Data.Resource			as Data.Resource
import qualified	WeekDaze.Size				as Size
import qualified	WeekDaze.Temporal.FreePeriodPreference	as Temporal.FreePeriodPreference

-- | Used to qualify XML.
groupMembershipTag :: String
groupMembershipTag	= "groupMembership"

-- | The default value for 'getGroupMembership'.
defaultGroupMembership :: Data.Group.Membership
defaultGroupMembership	= Data.Set.empty

-- | Describes a /resource/, which is also a person.
class HumanResource h where
	getNTimeslotsPerWeekOfTeaching
		:: Size.NTimeslots										-- ^ The number of /time-slot/s per /day/.
		-> h
		-> Size.NTimeslots										-- ^ The number of those /time-slot/s when the person is available, devoted to teaching or being taught.

	getNTimeslotsPerWeekOfNonTeaching
		:: Size.NTimeslots										-- ^ The number of /time-slot/s per /day/.
		-> h
		-> Size.NTimeslots										-- ^ The number of those /time-slot/s when the person is available, devoted to any activity other than teaching; e.g. lunch, meetings, administration, free-study.

	getGroupMembership		:: h -> Data.Group.Membership						-- ^ The /group/s to which this /human-resource/ belongs.

	getMaybeFreePeriodPreference	:: h -> Maybe Temporal.FreePeriodPreference.FreePeriodPreference	-- ^ Any preference for the position within each /day/, of unallocated /time-slot/s.

-- | The number of /time-slot/s in each week, that this /resource/ is regularly scheduled to be /available/.
calculateNTimeslotsPerWeekAvailable
	:: Data.Resource.Resource resource
	=> Size.NTimeslots
	-> resource
	-> Size.NTimeslots
calculateNTimeslotsPerWeekAvailable nTimeslotsPerDay	= (nTimeslotsPerDay *) . Data.Resource.countDaysPerWeekAvailable

-- | Finds the set of /group/s, of which at least one /human-resource/ claims membership.
extractDistinctGroupMembership :: HumanResource humanResource => Data.Resource.ResourceMap humanResourceId humanResource -> Data.Group.Membership
extractDistinctGroupMembership	= Data.Map.foldr (Data.Set.union . getGroupMembership) Data.Set.empty

-- | Identify those /human-resource/s, in the specified /resource/-map, who belong to the specified /group/.
extractGroupMembersOf
	:: HumanResource humanResource
	=> Data.Group.Id
	-> Data.Resource.ResourceMap humanResourceId humanResource
	-> Data.Resource.ResourceMap humanResourceId humanResource
extractGroupMembersOf groupId	= Data.Map.filter (Data.Set.member groupId . getGroupMembership)

-- | Get the union of all group-memberships.
extractCombinedGroupMembership
	:: HumanResource humanResource
	=> Data.Resource.ResourceMap humanResourceId humanResource
	-> Data.Group.Membership
extractCombinedGroupMembership	= Data.Set.unions . map getGroupMembership . Data.Map.elems

-- | Whether the /human-resource/ has specified a preference for the position, within each /day/ on which they're /available/, of free /time-slot/s.
hasFreePeriodPreference :: HumanResource humanResource => humanResource -> Bool
hasFreePeriodPreference	= Data.Maybe.isJust . getMaybeFreePeriodPreference