ddd_sample_app_ruby
ddd_sample_app_ruby copied to clipboard
Cargo tracking form
Implement cargo tracking form. User can enter tracking id and the cargo information will be displayed:
- tracking ID
- transport status
- next expected activity
- destination
- eta
- handling events sorted by completion time (icon to show whether each event is expected or not)
In .NET port Track.aspx form has:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<CargoTrackingViewAdapter>" %>
<%@ Import Namespace="DDDSample.UI.BookingAndTracking.Models"%>
<asp:Content ID="trackCargoTitle" ContentPlaceHolderID="TitleContent" runat="server">
Track your cargo
</asp:Content>
<asp:Content ID="trackCargoContent" ContentPlaceHolderID="MainContent" runat="server">
<%= Html.ValidationSummary() %>
<% using (Html.BeginForm())
{ %>
<div id="TrackingId">
<span>
<label for="trackingId">
Enter your tracking id:</label>
</span><span>
<%= Html.TextBox("trackingId") %>
<%= Html.ValidationMessage("trackingId", "*")%>
</span><span>
<input type="submit" value="Track!" />
</span>
</div>
<% } %>
<% if (Model != null) { %>
<div id="TrackingDetails">
<h2><%=Model.StatusText %></h2>
<p>Estimated time of arrival in <%=Model.Destination %>: <%=Model.Eta %></p>
<p><%=Model.NextExpectedActivity %></p>
<h3>Handling History</h3>
<ul style="list-style-type: none;">
<% foreach (HandlingEventViewAdapter @event in Model.HandlingEvents)
{ %>
<li>
<p>
<% if (@event.IsExpected)
{%>
<img style="vertical-align: top;" src="../../Content/images/tick.png" alt=""/>
<%}
else
{%>
<img style="vertical-align: top;" src="../../Content/images/error.png" alt=""/>
<%} %>
<%[email protected]%></p>
</li>
<% } %>
</ul>
<p><%=Html.ActionLink("Register new handling event", "RegisterHandlingEvent", "Handling", new { trackingId = Model.TrackingId}, null)%></p>
</div>
<% } %>
</asp:Content>
It uses CargoTrackingViewAdapter as a wrapper around the Cargo and (associated) Handling Event aggregate to keep the domain objects isolated from the UI concerns. Some code of interest is:
public string StatusText
{
get
{
switch (_cargo.Delivery.TransportStatus)
{
case TransportStatus.InPort:
return Resources.Messages.cargo_status_IN_PORT.UIFormat(_cargo.Delivery.LastKnownLocation.Name);
case TransportStatus.OnboardCarrier:
return Resources.Messages.cargo_status_ONBOARD_CARRIER.UIFormat("XXX");
case TransportStatus.Claimed:
return Resources.Messages.cargo_status_CLAIMED.UIFormat();
case TransportStatus.NotReceived:
return Resources.Messages.cargo_status_NOT_RECEIVED.UIFormat();
case TransportStatus.Unknown:
return Resources.Messages.cargo_status_UNKNOWN.UIFormat();
}
throw new NotSupportedException();
}
}
public String NextExpectedActivity
{
get
{
HandlingActivity activity = _cargo.Delivery.NextExpectedActivity;
if (activity == null)
{
return "";
}
const string text = "Next expected activity is to ";
HandlingEventType type = activity.EventType;
if (type == HandlingEventType.Load)
{
return
text + type.ToString().ToLower() + " cargo onto voyage XXX" +
" in " + activity.Location.Name;
}
if (type == HandlingEventType.Unload)
{
return
text + type.ToString().ToLower() + " cargo off of XXX" +
" in " + activity.Location.Name;
}
return text + type.ToString().ToLower() + " cargo in " + activity.Location.Name;
}
}
public string Eta
{
get
{
DateTime? eta = _cargo.Delivery.EstimatedTimeOfArrival;
return eta.HasValue ? eta.ToString() : "?";
}
}