Ship File

This commit is contained in:
Andy Howard
2019-07-09 16:47:08 +01:00
parent 887e981612
commit 8806c17edb
9 changed files with 325 additions and 162 deletions
@@ -22,7 +22,7 @@ namespace Sarand.LogisticsMgr.Mobile.App.Commands
public override bool CanExecute (object commandParam)
{
String fn = GetType().Name + ".CanExecute";
if (SacsSystem.DebugMode) Logger.Debug(fn + " Can view: " + SecurityProfile.Assets.CanView + ". Site: " + Site + ". Is applicable: " + SlmAppConsole.IsViewApplicable(Site, Slm.View.Assets_Movements));
//if (SacsSystem.DebugMode) Logger.Debug(fn + " Can view: " + SecurityProfile.Assets.CanView + ". Site: " + Site + ". Is applicable: " + SlmAppConsole.IsViewApplicable(Site, Slm.View.Assets_Movements));
if (!SecurityProfile.Assets.CanView) return false;
if (!SlmAppConsole.IsViewApplicable(Site, Slm.View.Assets_Movements)) return false;
return true;
@@ -191,8 +191,8 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Pages.Templates
{
// Page size has changed.
// Adjust main body padding.
double widthPadding = Math.Max(SlmMobile.PageBodyPaddingHorizontalMin, (Width - 460) / 2);
double heightPadding = Math.Max(SlmMobile.PageBodyPaddingVerticalMin, (Height - 800) / 20);
double widthPadding = Math.Max(SlmMobile.PageBodyPaddingHorizontalMin, (Width - 460) / 3);
double heightPadding = Math.Max(SlmMobile.PageBodyPaddingVerticalMin, (Height - 800) / 40);
pageBodyScroll.Padding = new Thickness(widthPadding, heightPadding);
pageBodyStatic.Padding = new Thickness(widthPadding, heightPadding);
}
@@ -92,6 +92,7 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Panels.Main
//-------------------------------------------------------------------
// Properties.
protected override String HeaderCaption { get { return "Assets - Movements"; } }
//-------------------------------------------------------------------
// I n i t i l i a s e C o m p o n e n t s
@@ -100,7 +101,6 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Panels.Main
protected override void InitialiseComponents ()
{
base.InitialiseComponents();
//Logger.Debug("List view row height: "+viewGrid.RowDefinitions[1].Height);
ConfigureComponents();
}
@@ -144,21 +144,22 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Panels.Main
public SlmAssetMovement.Params GetAssetMovementParams (uint pageNo, ushort pageLength)
{
SlmAssetMovement.Params assetMovementParams = new SlmAssetMovement.Params();
// Mode.
if (config.Mode == PanelMode.InProgress)
assetMovementParams.StatusCat = SlmAssetMovement.StatusCat.NotClosed;
// Filter.
assetMovementParams.AssetCodePartial = HeaderPanel.PanelFilter.GetFilterPropertyValue((int)FilterProperty.Code);
assetMovementParams.AssetSizeCodePartial = HeaderPanel.PanelFilter.GetFilterPropertyValue((int)FilterProperty.Size);
assetMovementParams.StatusCat = SlmAssetMovement.StatusCat.NotDeleted;
// Paging.
assetMovementParams.ResultsPaging.PageNo = pageNo;
assetMovementParams.ResultsPaging.PageLength = pageLength;
// Mode.
if (config.Mode == PanelMode.InProgress)
assetMovementParams.StatusCat = SlmAssetMovement.StatusCat.NotClosed;
return assetMovementParams;
}
private SacsTaskData taskDataRefreshList = null;
protected override void RefreshItemList (uint pageNo = 1)
{
String fn = GetType().Name + ".RefreshList";
String fn = GetType().Name + ".RefreshItemList";
// Kill previous request.
if (taskDataRefreshList != null)
@@ -175,7 +176,7 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Panels.Main
}
private void RefreshItemList (SlmAssetMovement.Params assetMovementParams, SacsTaskData taskDataRefreshList_Local)
{
String fn = GetType().Name + ".RefreshList";
String fn = GetType().Name + ".RefreshItemList";
// Query data after delay.
Device.StartTimer(TimeSpan.FromMilliseconds(250), () =>
@@ -312,25 +313,6 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Panels.Main
//-------------------------------------------------------------------
// P a n e l E v e n t s
//-------------------------------------------------------------------
//-------------------------------------------------------------------
protected override void OnParentSet ()
{
base.OnParentSet();
}
//-------------------------------------------------------------------
protected override void OnPropertyChanging ([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanging(propertyName);
}
protected override void OnPropertyChanged ([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
}
//-------------------------------------------------------------------
protected override void OnSizeAllocated (double width, double height)
{
base.OnSizeAllocated(width, height);
}
//-------------------------------------------------------------------
}
@@ -37,6 +37,7 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Panels.Main
//-------------------------------------------------------------------
// Properties.
protected abstract String HeaderCaption { get; }
public ushort ItemsPerPage { get; protected set; } = 8;
protected SaxPanel_ItemListHeader HeaderPanel { get; private set; }
protected SlmWebView ItemListWebView { get; private set; } = new SlmWebView();
@@ -58,7 +59,9 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Panels.Main
// Header panel.
SaxPanel_ItemListHeader.Config headerPanelConfig = new SaxPanel_ItemListHeader.Config();
headerPanelConfig.Caption = "Assets - Movements";
headerPanelConfig.Caption = HeaderCaption;
headerPanelConfig.LabelMargin = SlmMobile.LabelMargin;
headerPanelConfig.LabelFontSizeRatio = SlmMobile.FontSizeRatio;
headerPanelConfig.FilterPropertyTypes.AddRange(GetFilterPropertyTypes());
HeaderPanel = new SaxPanel_ItemListHeader(headerPanelConfig);
gridRowIdx++;
@@ -85,7 +85,7 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Panels.Main
componentGrid.Children.Add(loginComponents.LabelEmail, 0, gridRowIdx);
componentGrid.Children.Add(loginComponents.EntryEmail, 1, gridRowIdx);
Grid.SetColumnSpan(loginComponents.EntryEmail, 2);
if (SacsSystem.DebugMode) loginComponents.EntryEmail.Text = "andy@sarand.com";
if (SacsSystem.DebugMode && StringUtil.IsEmpty(loginComponents.EntryEmail.Text)) loginComponents.EntryEmail.Text = "andy@sarand.com";
// Password.
gridRowIdx++;
@@ -1,4 +1,11 @@
using Sarand.Core.Mobile.Forms.Controls;
using Sarand.Core.App;
using Sarand.Core.Base;
using Sarand.Core.Mobile.Forms.Controls;
using Sarand.Core.Mobile.Forms.Panels;
using Sarand.Core.Tasks;
using Sarand.LogisticsMgr.Core.App;
using Sarand.LogisticsMgr.Core.Bus;
using Sarand.LogisticsMgr.Core.WebService;
using Sarand.LogisticsMgr.Mobile.Core.App;
using Sarand.LogisticsMgr.Mobile.Core.Forms.Base;
using Sarand.LogisticsMgr.Mobile.Forms.Components;
@@ -6,23 +13,51 @@ using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace Sarand.LogisticsMgr.Mobile.Forms.Panels.Main
{
//=======================================================================
public class SlmMainPanel_ShipFile : SlmMainPanel
public class SlmMainPanel_ShipFile : SlmMainPanel_ItemList
{
//-------------------------------------------------------------------
// Definitions.
public new class Config : SlmMainPanel.Config
public enum FilterProperty
{
Vessel,
}
public enum PanelMode
{
Last2Weeks
}
public new class Config : SlmMainPanel_ItemList.Config
{
public PanelMode Mode { get; set; } = PanelMode.Last2Weeks;
}
//-------------------------------------------------------------------
// Data members
private Config config;
private SlmGrid viewGrid = new SlmGrid();
private class Columns
{
public ColumnDfn Id { get; set; }
public ColumnDfn VesselId { get; set; }
public ColumnDfn VesselName { get; set; }
public ColumnDfn AgentId { get; set; }
public ColumnDfn AgentName { get; set; }
public ColumnDfn CustomerName { get; set; }
public ColumnDfn CustomerId { get; set; }
public ColumnDfn Berth { get; set; }
public ColumnDfn Bollard { get; set; }
public ColumnDfn Expected { get; set; }
public ColumnDfn Arrived { get; set; }
public ColumnDfn Completed { get; set; }
public ColumnDfn Departed { get; set; }
public ColumnDfn Flags { get; set; }
public ColumnDfn Status { get; set; }
}
private Columns cols = new Columns();
//-------------------------------------------------------------------
// Construction.
@@ -30,37 +65,39 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Panels.Main
base(config)
{
this.config = config;
// Columns.
cols.Id = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.Id);
cols.VesselId = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.VesselId);
cols.VesselName = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.Vessel_Name);
cols.AgentId = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.AgentId);
cols.AgentName = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.Agent_Name);
cols.CustomerId = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.CustomerId);
cols.CustomerName = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.Customer_Name);
cols.Berth = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.Berth);
cols.Bollard = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.Bollard);
cols.Expected = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.Expected);
cols.Arrived = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.Arrived);
cols.Completed = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.Completed);
cols.Departed = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.Departed);
cols.Flags = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.Flags);
cols.Status = BerthingMgr.GetBerthingColumnDfn(SlmBerthing.Column.Status);
// Initialise components.
InitialiseComponents();
}
//-------------------------------------------------------------------
// Properties.
protected override String HeaderCaption { get { return "Ship File"; } }
//-------------------------------------------------------------------
// I n i t i l i a s e C o m p o n e n t s
//-------------------------------------------------------------------
/// <summary>Control initialisation on construction.</summary>
protected void InitialiseComponents ()
protected override void InitialiseComponents ()
{
// Configuration grid.
Content = viewGrid;
viewGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
viewGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });
int gridRowIdx = -1;
base.InitialiseComponents();
// Caption.
gridRowIdx++;
viewGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
SaxLabel labelCaption = new SaxLabel() { Text="Ship File"};
viewGrid.Children.Add(labelCaption, 0, gridRowIdx);
Grid.SetColumnSpan(labelCaption, 2);
}
//-------------------------------------------------------------------
// S e s s i o n P r o f i l e E v e n t s
//-------------------------------------------------------------------
private void SessionProfile_PropertyModified (object sender, EventArgs e)
{
ConfigureComponents();
}
//-------------------------------------------------------------------
@@ -69,6 +106,10 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Panels.Main
/// <summary>Control configuration that can be changed dynamically.</summary>
protected override void ConfigureComponents ()
{
base.ConfigureComponents();
// Initial population.
RefreshItemList();
}
//-------------------------------------------------------------------
@@ -85,27 +126,186 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Panels.Main
{
}
//-------------------------------------------------------------------
// I t e m L i s t
//-------------------------------------------------------------------
protected override List<SacsFilterPropertyType> GetFilterPropertyTypes ()
{
List<SacsFilterPropertyType> filterPropertyTypes = new List<SacsFilterPropertyType>();
filterPropertyTypes.Add(new SacsFilterPropertyType((int)FilterProperty.Vessel, "Vessel") { Mode = SacsFilterPropertyType.FilterMode.Text });
return filterPropertyTypes;
}
public SlmBerthing.Params GetBerthingParams (uint pageNo, ushort pageLength)
{
SlmBerthing.Params berthingParams = new SlmBerthing.Params();
// Filter.
berthingParams.VesselPartial = HeaderPanel.PanelFilter.GetFilterPropertyValue((int)FilterProperty.Vessel);
berthingParams.StatusCat = SlmBerthing.StatusCat.NotDeleted;
// Paging.
berthingParams.ResultsPaging.PageNo = pageNo;
berthingParams.ResultsPaging.PageLength = pageLength;
// Mode.
if (config.Mode == PanelMode.Last2Weeks)
berthingParams.ArrivedFrom = DateUtil.IncrementDate(DateTime.Today, -14);
return berthingParams;
}
private SacsTaskData taskDataRefreshList = null;
protected override void RefreshItemList (uint pageNo = 1)
{
String fn = GetType().Name + ".RefreshItemList";
// Kill previous request.
if (taskDataRefreshList != null)
{
taskDataRefreshList.TriggerCancellation();
taskDataRefreshList = null;
}
// Clear existing list.
DisplayItemList(null, "Refreshing list. Please wait...");
// Refresh the list.
RefreshItemList(GetBerthingParams(pageNo, ItemsPerPage), taskDataRefreshList = new SacsTaskData(null));
}
private void RefreshItemList (SlmBerthing.Params berthingParams, SacsTaskData taskDataRefreshList_Local)
{
String fn = GetType().Name + ".RefreshItemList";
// Query data after delay.
Device.StartTimer(TimeSpan.FromMilliseconds(250), () =>
{
if (SacsSystem.DebugMode) Logger.Debug(fn + " Timer fired.");
Task.Run(async () =>
{
try
{
// Configure request.
SlmWebServiceRequest.Config configRequest = new SlmWebServiceRequest.Config();
configRequest.DataType = SlmWebServiceRequest.DataType.Berthing;
configRequest.RequestType = SlmWebServiceRequest.RequestType.List;
configRequest.Context.SiteDefinition = SlmGlobals_Mobile.SessionProfile.SiteDefinition;
configRequest.Context.Debug = SacsSystem.DebugMode;
// Filter.
Dictionary<String, String> filter = BerthingMgr.GetBerthingQueryFilter_Mobile(berthingParams);
// Columns.
List<String> queryColumns = new List<String>()
{
cols.Id.DataName,
cols.VesselId.DataName,
cols.VesselName.DataName,
cols.AgentId.DataName,
cols.AgentName.DataName,
cols.CustomerName.DataName,
cols.CustomerId.DataName,
cols.Berth.DataName,
cols.Bollard.DataName,
cols.Expected.DataName,
cols.Arrived.DataName,
cols.Completed.DataName,
cols.Departed.DataName,
cols.Flags.DataName,
cols.Status.DataName,
};
// Request User profile.
if (SacsSystem.DebugMode) Logger.Debug(fn + " Querying data - START");
SlmWebServiceClient.ItemListResponseData responseData =
await new SlmWebServiceClient().GetItemList(configRequest, filter, queryColumns, taskDataRefreshList_Local);
if (SacsSystem.DebugMode) Logger.Debug(fn + " Querying data - END Items: " + (responseData?.Items.Count.ToString() ?? "None") + (taskDataRefreshList_Local.IsCancellationRequested ? " [Cancelled]" : ""));
// Display item list.
Device.BeginInvokeOnMainThread(() =>
{
DisplayItemList(responseData);
});
}
catch (Exception exc) { Logger.Debug(fn + " " + exc.GetLogMessage(6)); }
}, taskDataRefreshList_Local.CancellationToken)
.ContinueWith(task =>
{
taskDataRefreshList_Local.Dispose();
if (taskDataRefreshList == taskDataRefreshList_Local)
taskDataRefreshList = null;
});
if (SacsSystem.DebugMode) Logger.Debug(fn + " Timer method complete.");
return false;
});
}
//-------------------------------------------------------------------
protected override void DisplayItemList (SlmWebServiceClient.ItemListResponseData responseData, SacsMessage message = null)
{
// Refresh paging properties.
if (responseData != null)
HeaderPanel.SetPaging(responseData.PageNo, responseData.PageLength, responseData.Total);
else HeaderPanel.SetPaging(0, 0, 0);
// Construct item list HTML.
string html = "<html><head>"+GetItemListStyles().Concat("\n")+"</head><body>";
if (message != null)
{
String messageClass = "inf";
switch (message.MessageLevel)
{
case SaMessageLevel.Fatal:
case SaMessageLevel.Exception:
case SaMessageLevel.Error:
messageClass = "err";
break;
case SaMessageLevel.Warning:
messageClass = "wrn";
break;
}
html += "<div class='msg " + messageClass + "'>" + message.Message + "</div>";
}
if (responseData == null)
{ }
else if (responseData.Items.Count > 0)
{
//html += "<div class='msg inf'>Movements found: " + responseData.Items.Count + "</div>";
foreach (var item in responseData.Items)
{
html += "<div class='item'>";
html += "<div class='floatl'>" + item.GetValue(cols.VesselName.DataName) + "</div>";
html += "<div class='floatr'>" + item.GetValue(cols.AgentName.DataName) + "</div>";
html += "<div class='clearb'></div>";
// Berthing status.
SaStatus berthingStatus = SacsSystem.GetStatusForCode(item.GetValue(cols.Status.DataName));
html += "<div class=''>Customer: " + item.GetValue(cols.CustomerName.DataName) + "</div>";
html += "<div class=''>Berth: " + item.GetValue(cols.Berth.DataName) + " </div>";
html += "<div class=''>Bollard: " + item.GetValue(cols.Bollard.DataName) + "</div>";
html += "<div class=''>Status: " + SacsSystem.GetStatusDesc(berthingStatus) + "</div>";
html += "<div class=''>Arrived: " + DateUtil.Format(item.GetDateTimeValue(cols.Arrived.DataName), "d-MMM-yyyy") + "</div>";
html += "<div class=''>Completed: " + DateUtil.Format(item.GetDateTimeValue(cols.Completed.DataName), "d-MMM-yyyy") + "</div>";
html += "<div class=''>Departed: " + DateUtil.Format(item.GetDateTimeValue(cols.Departed.DataName), "d-MMM-yyyy") + "</div>";
html += "</div>";
}
}
else html += "<div class='msg inf'>No movements found</div>";
html += "</body></html>";
ItemListWebView.Html = html;
//Logger.Debug("HTML: " + html);
}
private List<String> GetItemListStyles ()
{
return new List<string>()
{
"<style>" + SlmResourceConsole.GetTextResource(SlmResourceConsole.TextResource.SaBaseCss) + "</style>",
"<style>" + SlmResourceConsole.GetTextResource(SlmResourceConsole.TextResource.SlmBaseCss) + "</style>",
"<style>",
"body{padding:4px;font-size:12px;border:1px solid #808080;border-radius:8px;overflow-y:auto;}",
"div.msg{margin-bottom:4px;padding:4px;border:1px solid #C0C0C0;border-radius:4px;}",
"div.msg.inf{color:green;}",
"div.msg.wrn{color:orange;}",
"div.msg.err{color:red;}",
"td{padding:4px 4px;}",
"tr.other th, tr.other td{background-color:#f0f0f0;}",
"div.item{margin:0 0 4px 0;padding:4px;background-color:#f8f8f8;border:2px solid #808080;border-radius:8px;}",
"</style>"
};
}
//-------------------------------------------------------------------
// P a n e l E v e n t s
//-------------------------------------------------------------------
protected override void OnParentSet ()
{
base.OnParentSet();
}
//-------------------------------------------------------------------
protected override void OnPropertyChanging ([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanging(propertyName);
}
protected override void OnPropertyChanged ([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
}
//-------------------------------------------------------------------
protected override void OnSizeAllocated (double width, double height)
{
base.OnSizeAllocated(width, height);
}
//-------------------------------------------------------------------
}
@@ -62,6 +62,8 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Views
{
gridRowIdx++;
menuGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
// Exclude options that cannot be executed.
if (!option.Heading && !(option.Command?.CanExecute(null) ?? false)) continue;
// Menu header background colour.
if (option.Heading)
{
@@ -85,7 +87,7 @@ namespace Sarand.LogisticsMgr.Mobile.Forms.Views
if (option.Heading)
optionLabel.FontAttributes = FontAttributes.Bold;
menuGrid.Children.Add(optionLabel, 1, gridRowIdx);
if (option.Command?.CanExecute(null) ?? false)
if (option.Command != null)
{
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += (s, e) => { option.Command.Execute(null); InvokeMenuOptionClicked(); };