using System;
using System.Linq;
using System.Linq.Expressions;
using InABox.Core;
namespace Comal.Classes
{
///
/// An assignment represents an anticipated booking for an employee, much like a diary entry
///
///
[UserTracking("Assignments")]
[Caption("Assignments")]
public class Assignment : Entity, IPersistent, IRemotable, INumericAutoIncrement, IOneToMany, IOneToMany,
IOneToMany, ILicense, IJobActivity, IOneToMany, IJobScopedItem
{
[IntegerEditor(Editable = Editable.Hidden)]
[EditorSequence(1)]
public int Number { get; set; }
[DateEditor]
[EditorSequence(2)]
public DateTime Date { get; set; }
[EntityRelationship(DeleteAction.Cascade)]
[EditorSequence(3)]
public EmployeeLink EmployeeLink { get; set; }
// [EntityRelationship(DeleteAction.Cascade)]
// [EditorSequence(4)]
// public EquipmentLink Equipment { get; set; }
[TextBoxEditor]
[EditorSequence(5)]
public string Title { get; set; }
[MemoEditor]
[EditorSequence(6)]
public string Description { get; set; }
[EditorSequence(7)]
public AssignmentActivityLink ActivityLink { get; set; }
private class KanbanLookup : LookupDefinitionGenerator
{
public override Filter DefineFilter(Assignment[] items)
{
if (items == null || !items.Any())
return LookupFactory.DefineFilter();
return new Filter(x => x.Closed).IsEqualTo(DateTime.MinValue).And(x => x.EmployeeLink.ID)
.IsEqualTo(items.First().EmployeeLink.ID);
}
public override Columns DefineFilterColumns()
=> Columns.None().Add(x => x.EmployeeLink.ID);
}
[LookupDefinition(typeof(KanbanLookup))]
[EditorSequence(8)]
[EntityRelationship(DeleteAction.SetNull)]
public KanbanLink Task { get; set; }
[EditorSequence(9)]
public JobLink JobLink { get; set; }
private class JobITPLookup : LookupDefinitionGenerator
{
public override Filter DefineFilter(Assignment[] items)
{
if (items.Length == 1)
return new Filter(x => x.Job.ID).IsEqualTo(items.First().JobLink.ID);
return LookupFactory.DefineFilter();
}
public override Columns DefineFilterColumns()
=> Columns.None().Add(x => x.JobLink.ID);
}
[LookupDefinition(typeof(JobITPLookup))]
[EditorSequence(10)]
public JobITPLink ITP { get; set; }
[NullEditor]
[Obsolete("Replaced with Actual.Start", true)]
public TimeSpan Start { get; set; }
[NullEditor]
[Obsolete("Replaced with Actual.Duration", true)]
public TimeSpan Duration { get; set; }
[NullEditor]
[Obsolete("Replaced with Actual.Finish", true)]
public TimeSpan Finish { get; set; }
[EditorSequence(11)]
[CoreTimeEditor]
public TimeBlock Booked { get; set; }
[EditorSequence(12)]
[CoreTimeEditor]
public TimeBlock Actual { get; set; }
[TimestampEditor]
[RequiredColumn]
[EditorSequence(13)]
public DateTime Completed { get; set; }
[EditorSequence("Processing",1)]
public ActualCharge Charge { get; set; }
[TimestampEditor]
[EditorSequence("Processing",2)]
public DateTime Processed { get; set; }
[NullEditor]
[EntityRelationship(DeleteAction.Cascade)]
public LeaveRequestLink LeaveRequestLink { get; set; }
[NullEditor]
public DeliveryLink Delivery { get; set; }
[NullEditor]
[EntityRelationship(DeleteAction.SetNull)]
public InvoiceLink Invoice { get; set; }
[NullEditor]
public MeetingDetails Meeting { get; set; }
private class JobScopeLookup : LookupDefinitionGenerator
{
public override Filter DefineFilter(Assignment[] items)
{
var item = items?.Length == 1 ? items[0] : null;
if (item != null)
return new Filter(x => x.Job.ID).IsEqualTo(item.JobLink.ID).And(x => x.Status.Approved).IsEqualTo(true);
return new Filter(x => x.ID).None();
}
public override Columns DefineFilterColumns()
=> Columns.None().Add(x => x.JobLink.ID);
}
[LookupDefinition(typeof(JobScopeLookup))]
public JobScopeLink JobScope { get; set; }
public Expression> AutoIncrementField()
{
return x => x.Number;
}
public Filter AutoIncrementFilter()
{
return null;
}
public static TimeSpan EffectiveTime(TimeSpan actual, TimeSpan booked) => actual.Ticks != 0L ? actual : booked;
public TimeSpan EffectiveStartTime()
{
return EffectiveTime(Actual.Start, Booked.Start);
}
public DateTime EffectiveStart()
{
return Date.Add(EffectiveStartTime());
}
public TimeSpan EffectiveFinishTime()
{
// If we have an actual finish, always use that
// otherwise use EffectiveStart() + booked.duration
return EffectiveTime(
Actual.Finish,
EffectiveTime(Actual.Start, Booked.Start)
.Add(Booked.Duration)
);
}
public DateTime EffectiveFinish()
{
return Date.Add(
EffectiveFinishTime()
);
}
static Assignment()
{
LinkedProperties.Register(ass => ass.ActivityLink.Charge, chg => chg.Chargeable, ass => ass.Charge.Chargeable);
Classes.JobScope.LinkScopeProperties();
}
}
}