Realiserung erweitert
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Interfaces;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Helpers;
|
||||||
|
using Model = Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Models;
|
||||||
|
|
||||||
|
using Gebhardt.StoreWare.Wcs.HostBooking.InterfaceWcsWms.Interfaces;
|
||||||
|
|
||||||
|
|
||||||
|
using Gebhardt.Shared;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.Constants;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Gebhardt.StoreWare.Wcs.HostBooking.InterfaceWcsWms.Interfaces
|
||||||
|
{
|
||||||
|
public interface IHandleRecord<in THostMessage> where THostMessage : IHostMessage
|
||||||
|
{
|
||||||
|
bool Handle(THostMessage arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using Unity;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Interfaces;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Services;
|
||||||
|
using Gebhardt.StoreWare.Wcs.HostBooking.InterfaceWcsWms.Interfaces;
|
||||||
|
using Gebhardt.Shared.Process;
|
||||||
|
using Gebhardt.Shared.Process.ProducerConsumer;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Interfaces;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Models;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.EntityFramework;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.EntityFramework.Models;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Mapping;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Helpers;
|
||||||
|
|
||||||
|
using Gebhardt.Shared;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.Constants;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Gebhardt.StoreWare.Wcs.HostBooking.InterfaceWcsWms
|
||||||
|
{
|
||||||
|
internal class FromWmsBookingConsumer : Consumer<IHostMessage>
|
||||||
|
{
|
||||||
|
#region Private Fields
|
||||||
|
|
||||||
|
private readonly IUnityContainer _unityContainer;
|
||||||
|
private readonly IHostMessageFromWmsService _serviceFromWms;
|
||||||
|
|
||||||
|
#endregion Private Fields
|
||||||
|
|
||||||
|
#region Public Constructors
|
||||||
|
|
||||||
|
public FromWmsBookingConsumer(string name, int aliveTime, int queueLength, IUnityContainer unityContainer)
|
||||||
|
: base(name, aliveTime, true, queueLength)
|
||||||
|
{
|
||||||
|
_unityContainer = unityContainer;
|
||||||
|
_serviceFromWms = _unityContainer.Resolve<IHostMessageFromWmsService>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Public Constructors
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
|
||||||
|
public override bool DoWork(IHostMessage hostMessage)
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IHandleRecord<IHostMessage> handler = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//handler = _unityContainer.Resolve<IHandleRecord>(hostMessage.RecordType);
|
||||||
|
handler = (IHandleRecord<IHostMessage>)_unityContainer.Resolve(hostMessage.GetType()); //TODO test
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Write(LogLevel.Error, $"IHandleRecord on UnityContainer in RegisterFromWmsServices from MessageInitializer.cs not registired. '{e.Message}'");
|
||||||
|
}
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
hostMessage.Handle();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handler.Handle(hostMessage);
|
||||||
|
hostMessage.SetFinished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
//Log.WriteException(e);
|
||||||
|
string exceptionMessage = e.InnerException?.InnerException?.Message ?? e.InnerException?.Message ?? e.Message;
|
||||||
|
Log.Write(LogLevel.Error, $"Nachricht {hostMessage.RecordType} kann nicht verbucht werden: {exceptionMessage}");
|
||||||
|
hostMessage.SetFailed(e.Message);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_serviceFromWms.Update(hostMessage);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Public Methods
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Unity;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Interfaces;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Services;
|
||||||
|
using Gebhardt.StoreWare.Wcs.HostBooking.InterfaceWcsWms.Interfaces;
|
||||||
|
using Gebhardt.Shared.Process;
|
||||||
|
using Gebhardt.Shared.Process.ProducerConsumer;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Interfaces;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Models;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.EntityFramework;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.EntityFramework.Models;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Mapping;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Helpers;
|
||||||
|
|
||||||
|
using Gebhardt.Shared;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.Constants;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Gebhardt.StoreWare.Wcs.HostBooking.InterfaceWcsWms
|
||||||
|
{
|
||||||
|
internal class FromWmsBookingProducer : Producer<IHostMessage>
|
||||||
|
{
|
||||||
|
#region Private Fields
|
||||||
|
|
||||||
|
private bool _firstExecution = true;
|
||||||
|
|
||||||
|
private int _consumerQueueLength;
|
||||||
|
|
||||||
|
private bool _useLoadBalancing;
|
||||||
|
|
||||||
|
private readonly IUnityContainer _unityContainer;
|
||||||
|
|
||||||
|
private readonly IHostMessageFromWmsService _serviceFromWms;
|
||||||
|
|
||||||
|
#endregion Private Fields
|
||||||
|
|
||||||
|
#region Private Methods
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fügt im Dictionary dem angegebenen Consumer das Messagem hinzu
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dataForConsumers"></param>
|
||||||
|
/// <param name="consumer"></param>
|
||||||
|
/// <param name="hostMessage">FromWms - IHostMessage</param>
|
||||||
|
private void AddDataForConsumer(ref Dictionary<string, List<IHostMessage>> dataForConsumers, string consumer, IHostMessage hostMessage)
|
||||||
|
{
|
||||||
|
if (dataForConsumers.ContainsKey(consumer))
|
||||||
|
{
|
||||||
|
dataForConsumers[consumer].Add(hostMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dataForConsumers.Add(consumer, new List<IHostMessage> { hostMessage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Bestimmt den Consumer, der für den Datensatz verantwortlich ist
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="consumersWithDemand"></param>
|
||||||
|
/// <param name="criterion"></param>
|
||||||
|
/// <returns>Consumer Name, wenn ein passender Consumer in der lsite ist, null, wenn kein passender Consumer in der Liste ist</returns>
|
||||||
|
private string GetConsumerForBooking(List<string> consumersWithDemand, string criterion)
|
||||||
|
{
|
||||||
|
//Gibt es eine Letzte Stelle, sonst default
|
||||||
|
if (!criterion.IsNullOrEmptyOrDbEmpty())
|
||||||
|
{
|
||||||
|
//Wir entscheiden mit der letzten Stelle der LE, welcher LE-Consumer verbucht oder ob der default Consumer das tun muss
|
||||||
|
string endOfLe = criterion.Substring(criterion.Length - 1);
|
||||||
|
//Der Name des Consumer endet mit dem gleichen Zeichen
|
||||||
|
if (consumersWithDemand.Any(c => c.EndsWith(endOfLe)))
|
||||||
|
{
|
||||||
|
return consumersWithDemand.First(c => c.EndsWith(endOfLe));
|
||||||
|
}
|
||||||
|
//Soll dieses Message von einem speziellen Consumer bearbeitet werden? Aber dieser ist beschäftigt
|
||||||
|
else if (Regex.IsMatch(endOfLe, "[0-9]"))
|
||||||
|
{
|
||||||
|
//Message auslassen - keinem Consumer zuordnen
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//HU endet mit einem Zeichen, dass zu keinem Consumer passt also Default oder auslassen
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Default Consumer muss mit Default enden!
|
||||||
|
return consumersWithDemand.FirstOrDefault(c => c.EndsWith("Default"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Default Consumer muss mit Default enden!
|
||||||
|
return consumersWithDemand.FirstOrDefault(c => c.EndsWith("Default"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Private Methods
|
||||||
|
|
||||||
|
#region Protected Methods
|
||||||
|
|
||||||
|
protected override Dictionary<string, List<IHostMessage>> GetDataForConsumers(List<string> consumersWithDemand)
|
||||||
|
{
|
||||||
|
//TODO: jub evtl. die Messagem Stau Meldung aus KW übernehmen
|
||||||
|
Dictionary<string, List<IHostMessage>> dataForConsumers = new Dictionary<string, List<IHostMessage>>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using HostEntities db = new HostEntitiesFactory(HostEntities.DefaultConnectionStringName).Create();
|
||||||
|
if (consumersWithDemand.Count > 0)
|
||||||
|
{
|
||||||
|
List<IHostMessage> hostMessageEntries;
|
||||||
|
|
||||||
|
//es werden maximal so viele Messages abgerufen, wie ein einzelner Consumer annehmen könnte, damit das TryAdd sicher klappt und der Status nicht fälschlich
|
||||||
|
//gesetzt wird
|
||||||
|
if (_firstExecution)
|
||||||
|
{
|
||||||
|
//beim ersten mal nach Neustart werden auch die InProgress Messages nochmal mit abgerufen
|
||||||
|
//Ref == null damit nur Kopfnachrichten gefunden werden
|
||||||
|
hostMessageEntries = _serviceFromWms.GetAllEntries(a => a.Status == "Pending" || a.Status == "InProgress", takeCount: _consumerQueueLength).OrderBy(a => a.Id).ToList();
|
||||||
|
_firstExecution = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//sonst nur Messages, die noch an keinen Consumer gegeben wurden
|
||||||
|
//Ref == null damit nur Kopfnachrichten gefunden werden
|
||||||
|
hostMessageEntries = _serviceFromWms.GetAllEntries(a => a.Status == "Pending", takeCount: _consumerQueueLength).OrderBy(a => a.Id).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostMessageEntries.Any())
|
||||||
|
{
|
||||||
|
//ohne LoadBalancing erhält der erste Consumer alle Messages zum Verbuchen
|
||||||
|
if (!_useLoadBalancing)
|
||||||
|
{
|
||||||
|
//der Consumer muss also alle Messages verarbeiten und nicht nur loggen
|
||||||
|
dataForConsumers.Add(consumersWithDemand.FirstOrDefault() ?? string.Empty, hostMessageEntries);
|
||||||
|
//Status auf InProgress damit jede Message nur einmal abgerufen wird
|
||||||
|
hostMessageEntries.ForEach(message => message.Status = "InProgress");
|
||||||
|
Log.Write(LogLevel.Low, $"Kein LoadBalancing aktiv, {hostMessageEntries.Count} neue HostMessages für Consumer {consumersWithDemand.FirstOrDefault()} gefunden");
|
||||||
|
}
|
||||||
|
//mit LoadBalancing wird nach der letzen Ziffer der ersten HU der Message auf 10 Consumer verteilt,
|
||||||
|
//enthält die Message keine HU wird es an Consumer 11 übergeben.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Write(LogLevel.Low, $"LoadBalancing aktiv, {hostMessageEntries.Count} neue HostMessages gefunden, verteile auf Consumer");
|
||||||
|
|
||||||
|
foreach (IHostMessage message in hostMessageEntries)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FromWms entityFromWms = HostMessageFromWmsService.HostMapper.Map<FromWms>(message);
|
||||||
|
Log.Write(LogLevel.Low, $"Producerschleife für {entityFromWms}");
|
||||||
|
string consumer;
|
||||||
|
//keine HU in der Message, dann dem Default Consumer zuordnen
|
||||||
|
if (entityFromWms.LeNo.IsNullOrEmptyOrDbEmpty())
|
||||||
|
{
|
||||||
|
consumer = GetConsumerForBooking(consumersWithDemand, null);
|
||||||
|
//wenn der Default Consumer nicht in der Liste war, Message auslassen
|
||||||
|
if (consumer != null)
|
||||||
|
{
|
||||||
|
AddDataForConsumer(ref dataForConsumers, consumer, message);
|
||||||
|
//Status auf InProgress damit die Message nur einmal abgerufen wird
|
||||||
|
entityFromWms.Status = "InProgress";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Messages mit HU
|
||||||
|
else
|
||||||
|
{
|
||||||
|
consumer = GetConsumerForBooking(consumersWithDemand, entityFromWms.LeNo);
|
||||||
|
AddDataForConsumer(ref dataForConsumers, consumer, message);
|
||||||
|
//Status auf InProgress damit die Message nur einmal abgerufen wird
|
||||||
|
entityFromWms.Status = "InProgress";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.WriteException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.Write(LogLevel.Low, $"Producerschleife beendet");
|
||||||
|
}
|
||||||
|
//Status Updates für alle weitergereichten Messages
|
||||||
|
db.SaveChanges();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Write(LogLevel.Debug, 60, "Keine Messages in FromWms");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Write(LogLevel.Debug, 60, "Kein Consumer hat demand");
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataForConsumers;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.WriteException(e);
|
||||||
|
return dataForConsumers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Protected Methods
|
||||||
|
|
||||||
|
#region Public Constructors
|
||||||
|
|
||||||
|
public FromWmsBookingProducer(int workinterval, bool useLoadBalancing, int consumerQueueLength, IUnityContainer unityContainer) : base(typeof(FromWmsBookingProducer).Name, workinterval, true)
|
||||||
|
{
|
||||||
|
_unityContainer = unityContainer;
|
||||||
|
_serviceFromWms = _unityContainer.Resolve<IHostMessageFromWmsService>();
|
||||||
|
_consumerQueueLength = consumerQueueLength;
|
||||||
|
_useLoadBalancing = useLoadBalancing;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Public Constructors
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Gebhardt.StoreWare.Wcs.HostBooking.InterfaceWcsWms
|
||||||
|
{
|
||||||
|
|
||||||
|
public class FromWmsException : Exception
|
||||||
|
{
|
||||||
|
public FromWmsException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public FromWmsException(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using Unity;
|
||||||
|
using Gebhardt.StoreWare.Wcs.HostBooking.InterfaceWcsWms.MessageImplementation;
|
||||||
|
using Gebhardt.StoreWare.Wcs.HostBooking.InterfaceWcsWms.Interfaces;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Interfaces;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Models;
|
||||||
|
using Gebhardt.StoreWare.WcsWms.InterfaceWcsWms.Services;
|
||||||
|
|
||||||
|
namespace Gebhardt.StoreWare.Wcs.HostBooking.InterfaceWcsWms
|
||||||
|
{
|
||||||
|
public static class MessageInitializer
|
||||||
|
{
|
||||||
|
public static void RegisterFromWmsServices(this IUnityContainer unityContainer)
|
||||||
|
{
|
||||||
|
unityContainer.RegisterType<IHostMessageFromWmsService, HostMessageFromWmsService>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RegisterFromWmsHandlers(this IUnityContainer unityContainer)
|
||||||
|
{
|
||||||
|
|
||||||
|
unityContainer.RegisterType<IHandleRecord<TransportOrder>, TransportOrderHandler>("TransportOrder");
|
||||||
|
|
||||||
|
unityContainer.RegisterType<IHandleRecord<ShipmentTransportOrder>, ShipmentTransportOrderHandler>("ShipmentTransportOrder");
|
||||||
|
|
||||||
|
unityContainer.RegisterType<IHandleRecord<AcknowledgeTransportCompleted>, AcknowledgeTransportCompletedHandler>("AcknowledgeTransportCompleted");
|
||||||
|
|
||||||
|
unityContainer.RegisterType<IHandleRecord<DepartureNotification>, DepartureNotificationHandler>("DepartureNotification");
|
||||||
|
|
||||||
|
//unityContainer.RegisterType<IHandleRecord<RequestEmptyHuReport>, RequestEmptyHuReportHandler>("RequestEmptyHuReport");
|
||||||
|
|
||||||
|
unityContainer.RegisterType<IHandleRecord<HuChange>, HuChangeHandler>("HuChange");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
public static IOrderedQueryable<OrdersHost> ApplyWmsOrderingSequencerRetrievalTime(this IQueryable<OrdersHost> entity,
|
||||||
|
IWcsDbContext db)
|
||||||
|
{
|
||||||
|
var query = entity
|
||||||
|
.GroupJoin(
|
||||||
|
db.OrdersHost
|
||||||
|
.GroupBy(xx => xx.IdOrderWmsHead)
|
||||||
|
.Select(g => new
|
||||||
|
{
|
||||||
|
IdOrderWmsHead = g.Key,
|
||||||
|
SequencerRetrievalTime = g.Min(y => y.SequencerRetrievalTime)
|
||||||
|
}),
|
||||||
|
o => o.IdOrderWmsHead,
|
||||||
|
m => m.IdOrderWmsHead,
|
||||||
|
(o, m) => new { o, m }
|
||||||
|
)
|
||||||
|
.SelectMany(x => x.m.DefaultIfEmpty(), (x, m) => new { x.o, m })
|
||||||
|
.OrderByDescending(x => x.o.IsStolen)
|
||||||
|
.ThenByDescending(x => x.o.IsDirectPicking)
|
||||||
|
.ThenByDescending(x => x.m.SequencerRetrievalTime != null)
|
||||||
|
.ThenBy(x => x.m.SequencerRetrievalTime)
|
||||||
|
.ThenBy(x => x.o.Created)
|
||||||
|
.Select(x => x.o);
|
||||||
|
return (IOrderedQueryable<OrdersHost>) query;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
public static IQueryable<OrdersHost> ByCancelledSequencerOrder(this IQueryable<OrdersHost> entity)
|
||||||
|
{
|
||||||
|
return entity.Where(o => o.Source.Contains(WcsNames.SEQ) && o.Destination == MfcAllDestinations.StorageLoop2);
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
public static IQueryable<OrdersHost> ExcludeNextEmpty(this IQueryable<OrdersHost> entity)
|
||||||
|
{
|
||||||
|
return entity.Where(o => o.LeNo != LeTypeName.NextEmptyMiniloadSmall.ToString() && o.LeNo != LeTypeName.NextEmptyMiniloadBig.ToString());
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 145 KiB |
@@ -51,11 +51,29 @@ Schriftliche Ausarbeitung nur im Maße wie es die IHK will.
|
|||||||
|
|
||||||
|
|
||||||
## 00 Vorbereitung
|
## 00 Vorbereitung
|
||||||
### Status: 🟩 Active
|
### Status: ⬛ Done
|
||||||
|
|
||||||
- [x] Etra Repo Fork clonen
|
- [x] Etra Repo Fork clonen
|
||||||
- [ ] Zugang zur Etra Emulation prüfen
|
- [x] Zugang zur Etra Emulation prüfen
|
||||||
- [ ] ConveyorDispo debuggen
|
- [x] ConveyorDispo debuggen
|
||||||
|
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
## 00.5 ERD erstellen
|
||||||
|
### Status: ⬛ Done
|
||||||
|
|
||||||
|
Entity Relationship Diagramm der relevanten Tabellen der Datenbank erstellen.
|
||||||
|
|
||||||
|
- Destination
|
||||||
|
- LeType
|
||||||
|
- Le
|
||||||
|
- Location
|
||||||
|
- OrdersHost
|
||||||
|
- OrdersConveyor
|
||||||
|
- OrdersMiniload
|
||||||
|
- Aisle
|
||||||
|
- StorageDevice
|
||||||
|
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user