/// <summary>好みをコピーする /// </summary> /// <param name="src">元</param> /// <param name="dst">先</param> protected virtual void CopyFavorites(CScheduledDate src, CScheduledDate dst) { // メンバーのシフトの好み for (int i = 0; i < src.ValidMemberSize; i++) { CMember member = src[i].Member; for (int j = 0; j < member.PatternSize; j++) { CPattern pattern = src.GetMembersPattern(member, j); dst.SetPatternRank(member, pattern, j); } } // スケジュールのこのみをセットする CRequirePatterns req = dst.Require; if (req != null && req == src.Require) { for (int i = 0; i < req.ValidSize; i++) { CPattern pattern = req.GetValid(i); for (int j = 0; j < src.ValidMemberSize; j++) { CMember member = src.GetPatternsMember(pattern, j); dst.SetMemberRank(pattern, member, j); } } } }
/// <summary>勤務シフトの追加 /// </summary> /// <param name="pattern">追加するシフト</param> public virtual void AddPattern(CPattern pattern) { if (!selectedpatterns.Contains(pattern)) { selectedpatterns.Add(pattern); } }
/// <summary> /// 区切りになる時間 /// </summary> /// <returns>タイムスパンの配列</returns> public List <TimeSpan> GetPeriodTimes() { List <TimeSpan> ret = new List <TimeSpan>(); int max = ValidMemberSize; for (int i = 0; i < max; i++) { CMember member = GetValidMember(i); CSchedule schedule = GetSchedule(member); CPattern work = (schedule != null ? schedule.Pattern : null); if (work == null || work.BuiltIn) { // ヌルも同然 } else { // 存在する TimeSpan start = work.Start; TimeSpan end = work.End; if (!ret.Contains(start)) { // 開始時間 ret.Add(start); } if (!ret.Contains(end)) { // 終了時間 ret.Add(end); } } } return(ret); }
/// <summary> /// 稼動中のメンバーの数 /// </summary> /// <param name="time"></param> /// <returns></returns> public virtual List <CMember> GetTime2ValidMember(TimeSpan time) { List <CMember> ret = new List <CMember>(); int max = ValidMemberSize; for (int i = 0; i < max; i++) { CMember mbr = GetValidMember(i); CSchedule scd = GetSchedule(mbr); CPattern ptn = scd.Pattern; if (ptn == null) { // 何もしない } else if (ptn.BuiltIn) { // 何もしないって! } else { if (ptn.Start <= time && ptn.End >= time) { // 稼働時間中 ret.Add(mbr); } } } return(ret); }
/// <summary> /// シフトが変更された /// </summary> /// <param name="type"></param> /// <param name="source"></param> public void NotifyPatternsEdited(EnumTimeTableElementEventTypes type, CPattern source) { if (OnPatternsEdited != null && scheduleEditedEvnetIsValid) { EPatternsEditedEventArgs e = new EPatternsEditedEventArgs(type, source); OnPatternsEdited(this, e); } }
/// <summary>ターンの人数 /// </summary> /// <param name="pattern">勤務シフト</param> /// <returns>人数</returns> public virtual int GetRequire(CPattern pattern) { if (!Requires.ContainsKey(pattern)) { return(0); } return(Requires[pattern]); }
/// <summary>このオブジェクト内でのシフトの番号</summary> internal virtual int Id(CPattern p) { int ret = _pt.Length; for (int i = 0; i < _pt.Length; i++) { if (_pt[i].Equals(p)) { ret = i; } } return(ret); }
/// <summary>メンバーの好みのシフト</summary> public virtual CPattern GetPattern(int rank) { CPattern ret = CPattern.NULL; if (rank < _ps.Count) { ret = _ps[rank]; } if (ret == null) { ret = CPattern.NULL; } return(ret); }
/// <summary>指定された時間の稼動中(であるべき)人数 /// </summary> /// <param name="time">時間(時刻)</param> /// <returns>指定された時間の稼動中(であるべき)人数</returns> public virtual int GetPatternTotal(TimeSpan time) { int ret = 0; int validsize = ValidSize; for (int i = 0; i < validsize; i++) { CPattern pattern = GetValid(i); if (pattern.Start <= time && time <= pattern.Start + pattern.Scope) { ret += GetRequire(pattern); } } return(ret); }
/// <summary> /// メンバーは何日連続で働いているか? /// </summary> /// <param name="member">メンバー</param> /// <param name="max">最大値</param> /// <returns>メンバーは何日連続で働いているか</returns> public virtual int GetMemberContinues(CMember member, int max) { int ret = 0; DateTime work = this.Date; work = work.AddDays(-1); CScheduledDate wDate = TimeTable[work]; CPattern pattern = wDate[member].Pattern; while (pattern != null && !pattern.BuiltIn) { work = work.AddDays(-1); ret++; wDate = TimeTable[work]; pattern = wDate[member].Pattern; } return(ret); }
/// <summary>勤務シフトに対するメンバーのランクを設定する</summary> public virtual void SetMemberRank(CPattern p, CMember m, int rank) { if (!p.IsAvailable(Date)) { return; } PatternsMember pm = null; if (PatternToPatternsMember.ContainsKey(p)) { pm = PatternToPatternsMember[p]; } else { pm = new PatternsMember(this, p); PatternToPatternsMember[p] = pm; } pm.SetMember(rank, m); }
/// <summary>展開された人数 /// </summary> /// <param name="n">何番目?</param> /// <returns>n番目のシフトの人数</returns> public virtual CPattern GetExtractedPattern(int n) { CPattern retValue = null; int m = 0; for (int i = 0; i < Size(); i++) { CPattern pw = GetPattern(i); for (int j = 0; j < Requires[pw]; j++) { if (m == n) { retValue = pw; } m++; } } return(retValue); }
/// <summary>メンバーに対するシフトのランクを設定する</summary> public virtual void SetPatternRank(CMember m, CPattern p, int rank) { if (!m.IsAvailable(Date)) { return; } MembersPattern mp = null; if (MemberToMembersPattern.ContainsKey(m)) { mp = MemberToMembersPattern[m]; } else { mp = new MembersPattern(this, m); MemberToMembersPattern[m] = mp; } mp.SetPattern(rank, p); }
/// <summary>有効な人数 /// </summary> /// <param name="n">n番目?</param> /// <returns>n番目のシフトの人数</returns> public virtual CPattern GetValid(int n) { CPattern ret = null; int c = 0; for (int i = 0; i < Size(); i++) { CPattern work = GetPattern(i); if (GetRequire(work) > 0) { if (c == n) { ret = GetPattern(i); } c++; } } return(ret); }
/// <summary>メンバーの好みのシフトをセット</summary> public virtual void SetPattern(int rank, CPattern pattern) { if (rank == _ps.Count) { _ps.Add(pattern); } else if (rank > _ps.Count) { for (int i = _ps.Count; i < rank; i++) { _ps.Add(null); } SetPattern(rank, pattern); } else { _ps.Remove(pattern); _ps.Insert(rank, pattern); } }
/// <summary>勤務シフトのrank番目に好まれるメンバーを取得する</summary> public virtual CMember GetPatternsMember(CPattern p, int rank) { if (p == null) { // シフトがnullのとき return(null); } PatternsMember pm = null; if (PatternToPatternsMember.ContainsKey(p)) { pm = PatternToPatternsMember[p]; } else { pm = new PatternsMember(this, p); PatternToPatternsMember[p] = pm; } return(pm.GetMember(rank)); }
/// <summary>勤務シフトにおけるメンバーのランクを取得する</summary> public virtual int GetMemberRank(CPattern p, CMember m) { int ret = 0; while (ret < ValidMemberSize) { if (m == null) { if (GetPatternsMember(p, ret) == null) { break; } } else if (m.Equals(GetPatternsMember(p, ret))) { break; } ret++; } return(ret); }
/// <summary>メンバーの合計 指定した時間で働く予定の人数</summary> public virtual int GetMemberTotal(TimeSpan time) { int ret = 0; for (int i = 0; i < ValidMemberSize; i++) { CMember member = GetValidMember(i); CSchedule schedule = GetSchedule(member); if (schedule != null) { CPattern pattern = schedule.Pattern; if (pattern != null) { if (pattern.Start <= time && time <= pattern.End) { ret++; } } } } return(ret); }
/// <summary>区切りになる時間 /// </summary> /// <returns>タイムスパンの配列</returns> public List <TimeSpan> GetPeriodTimes() { List <TimeSpan> ret = new List <TimeSpan>(); int max = ValidSize; for (int i = 0; i < max; i++) { CPattern work = GetValid(i); TimeSpan start = work.Start; TimeSpan end = work.End; if (!ret.Contains(start)) { // 開始時間 ret.Add(start); } if (!ret.Contains(end)) { // 終了時間 ret.Add(end); } } return(ret); }
/// <summary> シフトのメンバーの好みを自動設定する /// </summary> /// <param name="sDate">スケジュール化された(自動設定対象の)日付</param> /// <param name="pattern">設定するシフト</param> protected virtual void SetFavoritePatternStand(CScheduledDate sDate, CPattern pattern) { if (!pattern.IsAvailable(sDate.Date)) { // シフトが無効なら処理を抜ける return; } List <CMember> Candicates = new List <CMember>(); // シフトの有効なメンバーのリストを作成する for (int i = 0; i < sDate.ValidMemberSize; i++) { CMember m = sDate.GetValidMember(i); for (int j = 0; j < m.PatternSize; j++) { CPattern pat = m.GetPattern(j); if (pattern.Equals(pat)) { Candicates.Add(m); } } } int candicateSize = Candicates.Count; // 作成したリストからシフトに対して好みを割り振る for (int i = 0; i < candicateSize; i++) { int rand = 0; if (Candicates.Count > 1) { rand = Random1.Next(Candicates.Count); } CMember member = Candicates[rand]; Candicates.Remove(member); sDate.SetMemberRank(pattern, member, i); } }
/// <summary>勤務シフトの追加不可 /// </summary> /// <param name="pattern">勤務シフト</param> public override void AddPattern(CPattern pattern) { // Do Nothing }
/// <summary> メンバーのシフトの好みを自動設定する /// </summary> /// <param name="sDate">スケジュール化された(自動設定対象の)日付</param> /// <param name="member">設定するメンバー</param> /// <param name="force">休みを気にするかどうか</param> protected virtual void SetFavoriteMemberStand(CScheduledDate sDate, CMember member, bool force) { // List <CPattern> Candicates = new List <CPattern>(); // メンバーの有効なシフトのリストを作成する for (int i = 0; i < member.PatternSize; i++) { CPattern pattern = member.GetPattern(i); if (pattern.IsAvailable(sDate.Date)) { CRequirePatterns require = sDate.Require; if (require != null) { for (int j = 0; j < require.ValidSize; j++) { CPattern reqpat = sDate.Require.GetValid(j); if (pattern.Equals(reqpat)) { Candicates.Add(pattern); } } } } } // 休み設定 int conu = member.ContinuasInt; int cont = sDate.GetMemberContinues(member, conu); int rest = conu - cont; // 候補の数 int candicateSize = Candicates.Count; // 作成したリストからメンバーに対して好みを割り振る for (int i = 0; i < candicateSize; i++) { int rand = 0; if (Candicates.Count > 1) { rand = Random1.Next(Candicates.Count); } CPattern pattern = Candicates[rand]; Candicates.Remove(pattern); if (member.IsAvalableDay(sDate.Date.DayOfWeek)) { // 稼動の曜日 if ((rest > i || conu <= 0) || force) { // 連続稼動の許容範囲内 sDate.SetPatternRank(member, pattern, i); } else { // 連続稼動の許容範囲外 sDate.SetPatternRank(member, CPattern.DAYOFF, i); } } else { // せっかく設定したんですが曜日の都合で・・・ sDate.SetPatternRank(member, CPattern.DAYOFF, i); } } }
/// <summary>人員配置をセットする /// </summary> /// <param name="n">n番目?</param> /// <param name="require">n番目の人数</param> public virtual void SetRequire(CPattern n, int require) { Requires[n] = require; }
/// <summary>勤務シフトの人数を取得する /// </summary> /// <param name="pattern">勤務シフト</param> /// <returns>勤務シフトの人数</returns> public override int GetRequire(CPattern pattern) { return(0); }
/// <summary>人員配置をセットする /// </summary> /// <param name="n">n番目?</param> /// <param name="require">n番目の人数</param> public override void SetRequire(CPattern n, int require) { }
/// <summary>実際に割り当てられた人数の加算</summary> public virtual void Add(CPattern p) { Add(Id(p)); }
/// <summary> 設定されたメンバーとシフトに対して組み合わせを作成する</summary> public virtual void Auto() { int[] memRnk = new int[ValidMemberSize]; bool[] memChk = new bool[ValidMemberSize]; for (int i = 0; i < ValidMemberSize; i++) { memRnk[i] = ValidMemberSize + 1; memChk[i] = false; } MemberCount memCnt = new MemberCount(this, Require); int i2 = 0, j = 0; //System.out.println("展開サイズ:" + getRequire().getExtractedSize()); if (Require == null) { return; } // while (i2 < Require.ExtractedSize) { j = 0; while (j < ValidMemberSize) { if (memChk[j]) { // もうすでに決定している //System.out.println("すでに決定している:" + i + ":" + j); } else { CMember m1 = GetValidMember(j); // i番目のメンバー CPattern p1 = GetMembersPattern(m1, i2); // メンバーがもっとも望むシフト //System.out.println(i + ":" + m1.getName() + ":" + p1); int m1rank = GetMemberRank(p1, m1); // ↑がシフトにとってどれぐらい望まれているか? if ((m1rank < memRnk[j]) && (p1 != null)) { // メンバーがシフトを希望していてランクが有効である if (memCnt.Addable(p1)) { // シフトに登録可能な人数内 GetSchedule(m1).Pattern = p1; memRnk[j] = m1rank; memChk[j] = true; memCnt.Add(p1); } else { // シフトに登録可能な人数外 for (int k = 0; k < ValidMemberSize; k++) { CMember compM = GetValidMember(k); CSchedule compS = GetSchedule(compM); CPattern compP = compS.Pattern; if (p1.Equals(compP)) { if (memRnk[k] > m1rank) { // GetSchedule(m1).Pattern = p1; memRnk[j] = m1rank; memChk[j] = true; // compS.Pattern = null; memRnk[k] = ValidMemberSize; memChk[k] = false; break; } } } } } } j++; } i2++; } }
private CPattern _p; // /// <summary>コンストラクタ</summary> public PatternsMember(CScheduledDate enclosingInstance, CPattern p) : base() { InitBlock(enclosingInstance); this._p = p; }
/// <summary>人数は追加可能ですか?</summary> public virtual bool Addable(CPattern p) { return(Addable(Id(p))); }
/// <summary>勤務シフトを含んでいるか? /// </summary> public bool Contains(CPattern pattern) { return(this.selectedpatterns.Contains(pattern)); }