initialize

This commit is contained in:
Pruefer
2025-06-06 09:15:13 +02:00
commit fa7c2730f1
5817 changed files with 1339670 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
<assembly>
<id>windows</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<files>
<file>
<!-- aus der app.config eine oib.adapter.config machen-->
<source>${basedir}/src/main/resources/app.config</source>
<destName>${simm.binary.name}.config</destName>
<outputDirectory>/</outputDirectory>
</file>
<file>
<source>${basedir}/src/main/resources/Readme.txt</source>
<outputDirectory>/</outputDirectory>
</file>
</files>
<fileSets>
<fileSet>
<directory>${basedir}/target</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*.exe</include>
</includes>
</fileSet>
<fileSet>
<directory>${basedir}/lib</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*</include>
</includes>
<excludes>
<exclude>ihas.properties</exclude>
<exclude>IMSApiDotNetTestclient.exe</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>

View File

@@ -0,0 +1,29 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>sources</id>
<baseDirectory>/</baseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.basedir}/src</directory>
</fileSet>
<fileSet>
<directory>${project.basedir}/lib</directory>
</fileSet>
<fileSet>
<directory>${project.basedir}/Properties</directory>
<filtered>true</filtered>
</fileSet>
<fileSet>
<directory>${project.basedir}/</directory>
<includes>
<include>*.cs</include>
<include>*.ico</include>
<include>*.csproj</include>
<include>*.sln</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@@ -0,0 +1,14 @@
namespace com.itac.mes.simm
{
/// <summary>
/// possible values for the configuration settings
/// </summary>
public enum ConfigCode
{
OFF = 0,
MES = 1,
SIMM = 2
}
}

View File

@@ -0,0 +1,187 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using Asm.As.Oib.Client;
using Asm.As.Oib.SiplaceSetupCenter.Contracts.Data;
using com.itac.mes.imsapi;
using com.itac.mes.imsapi.domain.container;
using com.itac.mes.tools;
namespace com.itac.mes
{
class ContainerCheckThread
{
private static string attributeName = "SIMM-ManualSetToZero";
public static int MIN_INTERVAL_SECONDS = 10;
private TimeSpan interval;
private Thread thread;
private IIMSApi imsapi;
private SetupCenterNotificationClient setupCenterNotificationClient;
private string stationNumber;
private IMSApiSessionContextStruct sessionContext;
private imsapi.domain.container.KeyValue[] materialBinFilters = new imsapi.domain.container.KeyValue[] { new imsapi.domain.container.KeyValue("MATERIAL_BIN_NUMBER", "*") };
private AttributeInfo[] attributes = new AttributeInfo[] { new AttributeInfo(attributeName, "1") };
private string[] materialBinResultKeys = new string[] { "MATERIAL_BIN_NUMBER" };
public ContainerCheckThread(TimeSpan interval, IIMSApi imsapi, IMSApiSessionContextStruct sessionContext, SetupCenterNotificationClient setupCenterNotificationClient, String stationNumber)
{
// none of those values must be null
this.interval = interval;
this.imsapi = imsapi;
this.setupCenterNotificationClient = setupCenterNotificationClient;
this.stationNumber = stationNumber;
this.sessionContext = sessionContext;
if (interval.TotalSeconds >= MIN_INTERVAL_SECONDS)
{
thread = new Thread(CheckContainers);
}
}
public void Start()
{
if (thread != null)
{
thread.Start();
}
}
public void CheckContainers()
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "start checking empty containers in MES (having attribute " + attributeName + "==1)");
while (true)
{
try
{
string[] resultValues;
int objectType = 2;
string attributeValue = "1";
int maxRows = 100;
imsapi.domain.container.KeyValue[] attributeFilters = new imsapi.domain.container.KeyValue[0];
// getContainers with attribute
int returnCode = imsapi.attribGetObjectsForAttributeValues(sessionContext, stationNumber, objectType, attributeName, attributeValue, maxRows, attributeFilters, materialBinResultKeys, out resultValues);
if (returnCode == 0)
{
// for every container:
// send this info to setupCenter and close them within SC
// if OK remove the attribute from the container, otherwise set appropriate attribute value
foreach (String containerId in resultValues)
{
consumePackagingUnitInSetupCenter(containerId);
}
}
else if (returnCode == -932 || returnCode > 0)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "no empty containers found");
}
else if (returnCode < 0)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "failed to retrieve empty containers from MES, apiRet Code=" + returnCode);
}
}
catch (Exception exception)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "processing empty containers failed", exception);
}
finally
{
DateTime nextRun = DateTime.Now + interval;
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "next run for checking empty containers (having attribute " + attributeName + "==1) in " + interval + " at " + nextRun.ToLongTimeString());
Thread.Sleep(interval);
}
}
}
protected void consumePackagingUnitInSetupCenter(string containerId)
{
// create an ASM packaging unit; for delete it is sufficient to have an UID only
PackagingUnit packagingUnit = new PackagingUnit();
packagingUnit.UID = containerId;
PackagingUnitConsumedReport packUnitConsumedReport = new PackagingUnitConsumedReport();
PackagingUnitLocation packagingUnitLocation = new PackagingUnitLocation();
packagingUnitLocation.PackagingUnit = packagingUnit;
packUnitConsumedReport.PackagingUnitLocations = new List<PackagingUnitLocation> { packagingUnitLocation };
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "raise delete packagingUnit " + containerId + " in SetupCenter");
try
{
setupCenterNotificationClient.RaisePackagingUnitConsumed(packUnitConsumedReport);
// delete Packaging unite succeeded
// remove attribute from container
/* example call:
attribRemoveAttributeValue()
stationNumber= 01010010
objectType= 2
objectNumber= 000197630005
objectDetail= -1
attributeCode= SIMM - ManualSetToZero
attributeValueKey= 1
------------------------------------------------------------------
Result_attribRemoveAttributeValue
.return_value= 0 ''
*/
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "remove attribute " + attributeName + " from container " + containerId);
int objectType = 2;
string objectDetail = "-1";
string attributeValueKey = "1";
int retValue = imsapi.attribRemoveAttributeValue(sessionContext, stationNumber, objectType, containerId, objectDetail, attributeName, attributeValueKey);
if (retValue != 0)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "removing attribute " + attributeName + " from container " + containerId + " failed");
}
else
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "removing attribute " + attributeName + " from container " + containerId + " succeded");
}
}
catch (Exception e)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "raise consumed event for packagingUnit " + containerId + " failed", e);
// modify attribute value
/* example call
attribAppendAttributeValues()
stationNumber= 01010010
objectType= 2
objectNumber= 000197630005
objectDetail= -1
bookDate= -1
allowOverWrite= 1
attributeUploadKeys.length= 3
attributeUploadKeys[0]= ATTRIBUTE_CODE
attributeUploadKeys[1]= ATTRIBUTE_VALUE
attributeUploadKeys[2]= ERROR_CODE
attributeUploadValues.length= 3
attributeUploadValues[0]= SIMM - ManualSetToZero
attributeUploadValues[1]= 3
attributeUploadValues[2]= 0
------------------------------------------------------------------
Result_attribAppendAttributeValues
.return_value= 0 ''
.attributeResultValues[] empty
*/
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "update attribute " + attributeName + " from container " + containerId + " to value 2");
int objectType = 2;
string objectDetail = "-1";
long bookDate = -1;
int allowOverwrite = 1;
string[] attributeUploadKeys = new string[] { "ATTRIBUTE_CODE", "ATTRIBUTE_VALUE", "ERROR_CODE" };
string[] attributeUploadValues = new string[] { attributeName, "2", "0" };
string[] attributeResultValues = null;
int retValue = imsapi.attribAppendAttributeValues(sessionContext, stationNumber, objectType, containerId, objectDetail,
bookDate, allowOverwrite, attributeUploadKeys, attributeUploadValues, out attributeResultValues);
if (retValue != 0)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "setting attribute " + attributeName + " from container " + containerId + " to value 2 failed");
}
}
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.itac.mes.imsapi;
namespace com.itac.mes.imsapi.data
{
public class MaterialBinBooking
{
public static string[] MAXIMAL_INFORMATION = new string[] { "ERROR_CODE", "MATERIAL_BIN_NUMBER", "MATERIAL_BIN_QTY_ACTUAL", "QUANTITY", "TRANSACTION_CODE" };
[ImsApiKey(Key = "MATERIAL_BIN_NUMBER")]
public string materialBinNumber;
[ImsApiKey(Key = "MATERIAL_BIN_QTY_ACTUAL")]
public int materialBinQuantityActual = 0;
[ImsApiKey(Key = "QUANTITY")]
public int quantity = 0;
[ImsApiKey(Key = "TRANSACTION_CODE")]
public string transactionCode;
[ImsApiKey(Key = "ERROR_CODE")]
public int errorCode = 0;
public int CompareTo(MaterialBinBooking obj)
{
if (materialBinNumber == null) return -1;
if (obj == null) return 1;
return materialBinNumber.CompareTo(obj.materialBinNumber);
}
}
}

View File

@@ -0,0 +1,49 @@
namespace com.itac.mes.proxy
{
public class MslLevel
{
/// <summary>
/// SetupCenter has it's own values for the MSL Levels. These are defined as constants
/// This function returns the value from MsdLevel as a String (lower case);
/// </summary>
/// <param name="mslLevel"></param>
/// <returns></returns>
public static string toString(int msdLevel)
{
switch (msdLevel)
{
case 1: return "1";
case 2: return "2";
case 3: return "2a";
case 4: return "3";
case 5: return "4";
case 6: return "5";
case 7: return "5a";
case 8: return "6";
default: return "1";
}
}
/// <summary>
/// convert a level as it is used in iTAC.MES.Suite to a value used in SetupCenter
/// </summary>
/// <param name="itacLevel"></param>
/// <returns></returns>
public static int toCode(string itacLevel)
{
switch (itacLevel)
{
case "1": return 1;
case "2": return 2;
case "2a": case "2A": return 3;
case "3": return 4;
case "4": return 5;
case "5": return 6;
case "5a": case "5A": return 7;
case "6": return 8;
default:
return 1;
}
}
}
}

View File

@@ -0,0 +1,594 @@
#region Namespace
using System;
using System.Diagnostics;
using System.Reflection;
using System.ServiceModel;
using com.itac.mes.tools;
using com.itac.mes.proxy;
using Imsapi = com.itac.mes.imsapi.domain.container;
using Asm.As.Oib.SiplaceSetupCenter.Contracts.Data;
using Asm.As.Oib.SiplaceSetupCenter.Contracts.Service;
using OibClient = Asm.As.Oib.Client;
using com.itac.mes.imsapi.domain.container;
using System.Collections.Generic;
using com.itac.mes.imsapi;
using com.itac.mes.imsapi.data;
using System.Configuration;
using com.itac.mes.simm;
#endregion
namespace Itac.Oib
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class SetupCenterExternalControlReceiver : ISiplaceSetupCenterExternalControl, IDisposable, IReceiver
{
#region Fields
private readonly OibClient.OibSetupCenterExternalControlEvents _oibSetupCenterExternalControlEvents;
private IIMSApi imsapi;
private IMSApiSessionContextStruct sessionContext;
private ItacXmlSerializer serializer;
private long firstASMTime = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
private long msdOpenTime = DateTime.MinValue.Ticks;
private long lastItacTimeTicks = new DateTime(3000, 12, 31, 23, 59, 59, DateTimeKind.Utc).Ticks;
private long firstItacTimeTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
/// <summary>
/// the station Number is configured, must not be empty and MUST exist and valid!!!
/// if the stationNumber is not valid (licensed etc) all requests are rejected!!
/// </summary>
private string stationNumber;
private int transactionCode;
// some optional values, default false
private bool mslLevelCheck;
private ConfigCode expirationMaster;
private ConfigCode mslMaster;
private ConfigCode quantityMaster;
#endregion
#region Constructor
public SetupCenterExternalControlReceiver(OibClient.OibSetupCenterExternalControlEvents oibSetupCenterExternalControlEvents, IIMSApi imsapi, IMSApiSessionContextStruct newSessionContext,
String stationNumber, int transactionCode,
ConfigCode quantityMaster, ConfigCode mslMaster, ConfigCode expirationMaster)
{
_oibSetupCenterExternalControlEvents = oibSetupCenterExternalControlEvents;
if (oibSetupCenterExternalControlEvents != null)
{
oibSetupCenterExternalControlEvents.Ping = Ping;
oibSetupCenterExternalControlEvents.GetNewPackagingUnitData = GetNewPackagingUnitData;
oibSetupCenterExternalControlEvents.GetPackagingUnitControlStatus = GetPackagingUnitControlStatus;
}
this.imsapi = imsapi;
this.sessionContext = newSessionContext;
this.stationNumber = stationNumber;
this.transactionCode = transactionCode;
this.quantityMaster = quantityMaster;
this.mslMaster = mslMaster;
this.expirationMaster = expirationMaster;
serializer = new ItacXmlSerializer();
// evaluate some optional parameters from appConfig file
if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["mslLevelCheck"]))
{
mslLevelCheck = bool.Parse(ConfigurationManager.AppSettings["mslLevelCheck"].ToString());
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "optional parameter 'mslLevelCheck' set '" + mslLevelCheck.ToString() + "'");
}
}
public void Dispose()
{
if (_oibSetupCenterExternalControlEvents != null)
_oibSetupCenterExternalControlEvents.Dispose();
}
#endregion
#region Start/Stop
public void StartReceiver()
{
_oibSetupCenterExternalControlEvents.Start();
}
public void StopReceiver()
{
_oibSetupCenterExternalControlEvents.Stop();
}
#endregion
#region toolFunctions
// muss noch weiter getestet werden...
public void DeepCopy(object sourceObject, object destObject)
{
Type sourceType = sourceObject.GetType();
Type destType = destObject.GetType();
MemberInfo[] sourceMbrInfoArray = sourceType.GetMembers();
MemberInfo[] destMbrInfoArray = destType.GetMembers();
foreach (MemberInfo sourceMbrInfo in sourceMbrInfoArray)
{
if (sourceMbrInfo.MemberType == MemberTypes.Property)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "" + sourceMbrInfo + " is a " + sourceMbrInfo.MemberType);
// alle einfachen TypeNameConverter direkt prüfen (int, String, bool)
// komplexe Typen ???
PropertyInfo sourcePropInfo = sourceType.GetProperty(sourceMbrInfo.Name);
// gibt es das Property auch im Zielobjekt
foreach (MemberInfo destMbrInfo in destMbrInfoArray)
{
// identischer Name, identischerr Typ
if (destMbrInfo.MemberType == sourceMbrInfo.MemberType && destMbrInfo.Name == sourceMbrInfo.Name)
{
PropertyInfo destPropInfo = destType.GetProperty(destMbrInfo.Name);
object sourceValue = sourcePropInfo.GetValue(sourceObject, null);
object destValue = destPropInfo.GetValue(destObject, null);
if (sourcePropInfo.PropertyType == typeof(String) || sourcePropInfo.PropertyType == typeof(int)
|| sourcePropInfo.PropertyType == typeof(Int32) || sourcePropInfo.PropertyType == typeof(Int64)
|| sourcePropInfo.PropertyType == typeof(long) || sourcePropInfo.PropertyType == typeof(bool)
|| sourcePropInfo.PropertyType == typeof(Boolean))
{
if (sourceValue != destValue)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "primitive type copy value");
destPropInfo.SetValue(destObject, sourceValue, null);
}
}
else if (!sourceType.IsArray)
{
// komplexer Typ, kein Array
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, sourceMbrInfo.Name + " is complex type ");
if (sourceValue != null)
{
DeepCopy(sourceValue, destValue);
}
else
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, sourceMbrInfo.Name + " is complex type, sourceValue is null");
}
}
}
}
}
}
}
public void applyToPackagingUnit(SmtContainer container, ref PackagingUnit p)
{
p.BatchId = container.supplierChargeNumber;
// p.BatchPackagingUnit=
p.BrightnessClass = container.classification; ;
// p.Comment="";
p.ComponentBarcode = "";
p.ComponentName = container.materialBinPartNumber;
// p.ConsumptionDate = getDateValue(resultValues[indexMap[""]]);
// special case: itac 31.12.3000 is unexpired, in ASM 31.12.9999
if (container.expirationDate >= new DateTime(2037, 12, 31))
{
p.ExpiryDate = DateTime.MaxValue.ToUniversalTime();
}
else
{
p.ExpiryDate = container.expirationDate; // getDateValue(resultValues[indexMap["EXPIRATION_DATE"]]);
}
// p.Extra1="";
// p.Extra2="";
// p.Extra3="";
// p.GreyZone=
if (p.LastProductionDate <= new DateTime(1901, 01, 01, 00, 00, 00, DateTimeKind.Utc))
{
p.LastProductionDate = DateTime.MinValue.ToUniversalTime();
}
// p.ManufactureLocation
// p.ManufacturePartNumber
p.Manufacturer = container.supplierName;
p.ManufacturerDate = container.dateCreated;
p.MsdLevel = MslLevel.toCode(container.mslLevel);
string mslState = container.mslState;
if ("C".Equals(mslState))
{
p.MsdOpenDate = DateTime.MinValue.ToUniversalTime();
}
else
{
// take open date from MES
p.MsdOpenDate = container.mslOpenDate;
// correction of MSD open Date when unopened
if (p.MsdOpenDate <= new DateTime(1901, 01, 01, 00, 00, 00, DateTimeKind.Utc))
{
p.MsdOpenDate = DateTime.MinValue.ToUniversalTime();
}
}
// p.OrderingCode = ;
p.OriginalQuantity = container.quantity;// Convert.ToInt32(double.Parse(resultValues[indexMap["MATERIAL_BIN_QTY_TOTAL"]]));
p.PurchaseOrderNumber = container.huNumber;
p.Quantity = container.materialBinQuantityActual; // Convert.ToInt32(Double.Parse(resultValues[indexMap["MATERIAL_BIN_QTY_ACTUAL"]]));
// p.RevisionLevel;
// p.RoHS
// p.Serial
// p.ShippingNoteNumber
// p.SplicedPackagingUnit
p.Supplier = container.supplierName;
// p.SupplierData
// p.UID;
}
public void mapValues(PackagingUnit pu, string[] materialBinUploadKeys, ref string[] result, int index)
{
foreach (string s in materialBinUploadKeys)
{
switch (s)
{
case "ERROR_CODE": result[index++] = "0"; break;
case "MATERIAL_BIN_NUMBER": result[index++] = pu.UID; break;
default: result[index++] = "0"; break;
}
}
}
public void deepAddUnit(PackagingUnit packUnit, ref Dictionary<string, PackagingUnit> packagingUnitMap)
{
packagingUnitMap.Add(packUnit.UID, packUnit);
if (packUnit.SplicedPackagingUnit != null)
{
deepAddUnit(packUnit.SplicedPackagingUnit, ref packagingUnitMap);
}
}
#endregion toolFunctions
#region ISiplaceSetupCenterExternalControl Members
/// <summary>
/// Check for the client if this service is available.
/// </summary>
/// <returns></returns>
public bool Ping()
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "SetupCenterExternalControl.Ping");
return true;
}
/// <summary>
/// Gets the packaging unit control status.
/// </summary>
/// <param name="packagingUnitLocations">The packaging unit locations.</param>
/// <returns>List of ExternalControlResults for reading the data</returns>
/// ResultState UNKNOWN=0;OK = 1;NOT_OK=2;
public ExternalControlResult[] GetNewPackagingUnitData(PackagingUnitLocation[] packagingUnitLocations)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "SetupCenterExternalControl.GetNewPackagingUnit()\n"
+ serializer.serialize(packagingUnitLocations).ToString());
Imsapi. KeyValue[] matBinfilters = new Imsapi.KeyValue[] { new Imsapi.KeyValue("MATERIAL_BIN_NUMBER", "") };
AttributeInfo[] attributes = new AttributeInfo[0];
string[] resultValues;
try
{
ExternalControlResult[] result = new ExternalControlResult[packagingUnitLocations.Length];
for (int i = 0; i < packagingUnitLocations.Length; i++)
{
result[i] = new ExternalControlResult();
result[i].PackagingUnit = packagingUnitLocations[i].PackagingUnit;
matBinfilters[0].value = packagingUnitLocations[i].PackagingUnit.UID;
int imsapiResult = imsapi.mlGetMaterialBinData(sessionContext, stationNumber, matBinfilters, attributes, SmtContainer.MAXIMAL_INFORMATION, out resultValues);
// return all relevant PackagingUnit infos known in iTAC.MES.Suite
if (imsapiResult < 0 || imsapiResult == 1) // 1 = no data found
{
result[i].ResultState = 2;
result[i].Messages = new List<ExternalControlResultMessage> { new ExternalControlResultMessage() };
result[i].Messages[0].Message = "UID " + packagingUnitLocations[i].PackagingUnit.UID + " unknown in iTAC.MES.Suite";
}
else
{
// OK, Info gathered
result[i].ResultState = 1;
result[i].Messages = new List<ExternalControlResultMessage> { };
PackagingUnit p = result[i].PackagingUnit;
try
{
SmtContainer knownContainer = new ImsApiMapTool<SmtContainer>().getStruct(typeof(SmtContainer), SmtContainer.MAXIMAL_INFORMATION, resultValues);
applyToPackagingUnit(knownContainer, ref p);
}
catch (Exception e)
{
result[i].ResultState = 2;
result[i].Messages = new List<ExternalControlResultMessage> { new ExternalControlResultMessage() };
result[i].Messages[0].Message = e.Message.ToString();
}
}
}
LogHandler.log(Constants.LOGGER, TraceEventType.Information, serializer.serialize(result).ToString());
return result;
}
catch (Exception)
{
// Fehler, keine weitere info vorhanden, da die Applikation nicht läuft
return new ExternalControlResult[0];
}
}
/// <summary>
/// Gets the packaging unit control status.
/// </summary>
/// <param name="packagingUnitLocations">The packaging unit locations.</param>
/// <returns>List of ExternalControlResults for reading the data</returns>
public ExternalControlResult[] GetPackagingUnitControlStatus(PackagingUnitLocation[] packagingUnitLocations)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "SetupCenterExternalControl.GetPackagingUnitControlStatus:\n"
+ serializer.serialize(packagingUnitLocations).ToString());
if (!mslLevelCheck)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "mslLevel check switched off by confguration");
}
Imsapi. KeyValue[] matBinfilters = new Imsapi.KeyValue[] { new Imsapi.KeyValue("MATERIAL_BIN_NUMBER", "") };
AttributeInfo[] attributes = new AttributeInfo[0];
// flag wether to update any qty or not.
LinkedList<MaterialBinBooking> updateQtyList = new LinkedList<MaterialBinBooking>();
try
{
ExternalControlResult[] result = new ExternalControlResult[packagingUnitLocations.Length];
for (int resultIndex = 0; resultIndex < packagingUnitLocations.Length; resultIndex++)
{
result[resultIndex] = new ExternalControlResult();
result[resultIndex].PackagingUnit = packagingUnitLocations[resultIndex].PackagingUnit;
PackagingUnit packagingUnit = packagingUnitLocations[resultIndex].PackagingUnit;
// ResultState UNKNOWN = 0; OK = 1; NOT_OK = 2;
result[resultIndex].ResultState = 1;
result[resultIndex].Messages = new List<ExternalControlResultMessage> { };
string[] resultValues;
matBinfilters[0].value = packagingUnitLocations[resultIndex].PackagingUnit.UID;
int imsapiResult = imsapi.mlGetMaterialBinData(sessionContext, stationNumber, matBinfilters, attributes, SmtContainer.MINIMAL_INFORMATION, out resultValues);
if (imsapiResult < 0 || imsapiResult == 1) // 1 = no data found
{
// Packaging Units unknown in MES.Suite must be rejected
// Error, Packaging Unit not found in mes.suite
result[resultIndex].ResultState = 2;
ExternalControlResultMessage message = new ExternalControlResultMessage();
message.Message = "PackagingUnit '" + packagingUnitLocations[resultIndex].PackagingUnit.UID + "' unknown in iTAC.MES.Suite";
result[resultIndex].Messages = new List<ExternalControlResultMessage> { message };
}
else
{
// find any differences in quantities and update the values in MES.Suite
SmtContainer knownContainer = new ImsApiMapTool<SmtContainer>().getStruct(typeof(SmtContainer), SmtContainer.MINIMAL_INFORMATION, resultValues);
LogHandler.log(Constants.LOGGER, TraceEventType.Information, serializer.serialize(knownContainer).ToString());
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "quantityMaster=" + quantityMaster);
adjustQuantity(quantityMaster, ref knownContainer, ref packagingUnit, ref updateQtyList);
// any differences in mslLevel?
if (mslLevelCheck)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "mslLevelCheck=true");
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} MsdLevel(ASM): {1}, MslLevel(iTAC): {2}", packagingUnit.UID, packagingUnit.MsdLevel, knownContainer.mslLevel));
if (!knownContainer.mslLevel.ToLower().Equals(MslLevel.toString(packagingUnit.MsdLevel)))
{
// failure, wrong MslLevel
result[resultIndex].ResultState = 2;
ExternalControlResultMessage message = new ExternalControlResultMessage();
message.Message = String.Format("PackagingUnit {0} has MsdLevel {1} in SetupCenter, but Level {2} in iTAC.MES.Suite",
packagingUnit.UID, MslLevel.toString(packagingUnit.MsdLevel), knownContainer.mslLevel);
result[resultIndex].Messages = new List<ExternalControlResultMessage> { message };
}
// continue with next container
continue;
}
// any differences in msl state?
if (mslMaster == ConfigCode.SIMM)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "mslMaster=" + mslMaster.ToString());
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} MsdOpen(ASM): {1}, MslState(iTAC): {2}", packagingUnit.UID, isMsdOpen(packagingUnit.MsdOpenDate), knownContainer.mslState));
// iTAC states : C = geschützt / verschweißt(Closed) O = ungeschützt / offen(Open) B = in der Rücktrocknung (Baking)
// ASM closed: MsdOpenDate = 2.1.1900
Imsapi. KeyValue[] mslEventParams = new Imsapi. KeyValue[] { new Imsapi.KeyValue("BOOK_DATE", getImsApiDateString(packagingUnit.MsdOpenDate)) };
Imsapi. KeyValue[] mslStopEventParams = new Imsapi.KeyValue[] { new Imsapi.KeyValue("BOOK_DATE", "-1") };
string[] mslObjectKeys = new String[] { "ERROR_CODE", "MATERIAL_BIN_NUMBER" };
string[] mslObjectValues = new String[] { "0", packagingUnit.UID };
string[] mslResultValues = new String[] { };
if (knownContainer.mslState.Equals("C") && isMsdOpen(packagingUnit.MsdOpenDate))
{
// closed in iTAC, open in ASM--> required to open in iTAC!!!
int mslStartExpirationCode = imsapi.mslStartObjectExpiration(sessionContext, stationNumber, mslEventParams, mslObjectKeys, mslObjectValues, out mslResultValues);
if (mslStartExpirationCode < 0)
{
result[resultIndex].ResultState = 2;
ExternalControlResultMessage message = new ExternalControlResultMessage();
message.Message = String.Format("PackagingUnit {0} not opened in iTAC.MES.Suite", packagingUnit.UID);
result[resultIndex].Messages = new List<ExternalControlResultMessage> { message };
continue;
}
}
else if (knownContainer.mslState.Equals("O") && !isMsdOpen(packagingUnit.MsdOpenDate) && packagingUnit.MsdOpenDate.Ticks > DateTime.MinValue.Ticks)
{
// open in iTAC, closed in ASM--> required to close in iTAC!!!
int mslStopExpirationCode = imsapi.mslStopObjectExpiration(sessionContext, stationNumber, mslStopEventParams, mslObjectKeys, mslObjectValues, out mslResultValues);
if (mslStopExpirationCode < 0)
{
result[resultIndex].ResultState = 2;
ExternalControlResultMessage message = new ExternalControlResultMessage();
message.Message = String.Format("PackagingUnit {0} not closed in iTAC.MES.Suite", packagingUnit.UID);
result[resultIndex].Messages = new List<ExternalControlResultMessage> { message };
continue;
}
}
}
else if (mslMaster == ConfigCode.MES)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Warning, "this mode is currently not supported!");
}
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "expirationMaster=" + expirationMaster.ToString());
if (!adjustExpiration(expirationMaster, ref knownContainer, ref packagingUnit, ref imsapi, ref result[resultIndex]))
{
continue;
}
// SiMM-Corrections
if (packagingUnit.MsdOpenDate <= new DateTime(1900, 01, 01)) { packagingUnit.MsdOpenDate = DateTime.MinValue.ToUniversalTime(); }
if (packagingUnit.ConsumptionDate <= new DateTime(1900, 01, 01)) { packagingUnit.ConsumptionDate = DateTime.MinValue.ToUniversalTime(); }
if (packagingUnit.ExpiryDate <= new DateTime(1900, 01, 01)) { packagingUnit.ExpiryDate = DateTime.MinValue.ToUniversalTime(); }
if (packagingUnit.LastProductionDate <= new DateTime(1900, 01, 01)) { packagingUnit.LastProductionDate = DateTime.MinValue.ToUniversalTime(); }
if (packagingUnit.ManufacturerDate <= new DateTime(1900, 01, 01)) { packagingUnit.ManufacturerDate = DateTime.MinValue.ToUniversalTime(); }
}
}
if (quantityMaster == ConfigCode.SIMM && updateQtyList.Count > 0)
{
MaterialBinBooking[] matBinBookingArray = new MaterialBinBooking[updateQtyList.Count];
updateQtyList.CopyTo(matBinBookingArray, 0);
string[] materialBinBookingUploadValues = new ImsApiMapTool<MaterialBinBooking>().getValueArray(matBinBookingArray, MaterialBinBooking.MAXIMAL_INFORMATION); ;
string[] materialBinBookingsResultValues = null;
int retUpdateQty = imsapi.mlUploadMaterialBinBooking(sessionContext, stationNumber, MaterialBinBooking.MAXIMAL_INFORMATION, materialBinBookingUploadValues, out materialBinBookingsResultValues);
}
LogHandler.log(Constants.LOGGER, TraceEventType.Information, serializer.serialize(result).ToString());
return result;
}
catch (Exception)
{
// Fehler, keine weitere info vorhanden, da die Applikation nicht läuft
return new ExternalControlResult[0];
}
}
public void adjustQuantity(ConfigCode quantityMaster, ref SmtContainer knownContainer, ref PackagingUnit packagingUnit, ref LinkedList<MaterialBinBooking> updateQtyList)
{
if (quantityMaster == ConfigCode.SIMM)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} Qty(ASM): {1}, Qty(iTAC): {2}", packagingUnit.UID, packagingUnit.Quantity, knownContainer.materialBinQuantityActual));
if (packagingUnit.Quantity != knownContainer.materialBinQuantityActual)
{
// udpate the MES with the quantity from ASM
MaterialBinBooking matBinBooking = new MaterialBinBooking();
matBinBooking.materialBinNumber = packagingUnit.UID;
matBinBooking.transactionCode = transactionCode.ToString();
matBinBooking.materialBinQuantityActual = packagingUnit.Quantity;
updateQtyList.AddLast(matBinBooking);
}
}
else if (quantityMaster == ConfigCode.MES)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} Qty(ASM): {1}, Qty(iTAC): {2}", packagingUnit.UID, packagingUnit.Quantity, knownContainer.materialBinQuantityActual));
if (packagingUnit.Quantity != knownContainer.materialBinQuantityActual)
{
packagingUnit.Quantity = knownContainer.materialBinQuantityActual;
}
}
}
public bool adjustExpiration(ConfigCode expirationMaster, ref SmtContainer knownContainer, ref PackagingUnit packagingUnit, ref IIMSApi imsapi, ref ExternalControlResult result)
{
if (expirationMaster == ConfigCode.SIMM)
{
if (packagingUnit.ExpiryDate == DateTime.MinValue)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} no expiration set", packagingUnit.UID));
return true;
}
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} expiryDate(ASM): {1}, expirationDate(iTAC): {2}", packagingUnit.UID, packagingUnit.ExpiryDate, knownContainer.expirationDate));
if (expirationDateDifferent(packagingUnit.ExpiryDate, knownContainer.expirationDate))
{
// update expirationDate in iTAC
Imsapi. KeyValue[] keyValueArray = new Imsapi.KeyValue[1];
keyValueArray[0] = new Imsapi.KeyValue("EXPIRATION_DATE_FINAL", getImsApiDateString(packagingUnit.ExpiryDate));
int changeBinResult = imsapi.mlChangeMaterialBinData(sessionContext, stationNumber, packagingUnit.UID, keyValueArray);
if (changeBinResult < 0)
{
// reject container
result.ResultState = 2;
ExternalControlResultMessage message = new ExternalControlResultMessage();
message.Message = String.Format("PackagingUnit {0} expiration date final not updated in iTAC.MES.Suite", packagingUnit.UID);
result.Messages = new List<ExternalControlResultMessage> { message };
return false;
}
}
}
else if (expirationMaster == ConfigCode.MES)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Warning, "this mode is currently not supported!");
return true;
}
return true;
}
public string getImsApiDateString(DateTime expiryDate)
{
if (expiryDate.Ticks >= lastItacTimeTicks)
{
return "32535212399000";
}
if (expiryDate.Ticks <= firstItacTimeTicks)
{
return "0";
}
return expiryDate.ToUniversalTime().Subtract(
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
).TotalMilliseconds.ToString();
}
public bool expirationDateDifferent(DateTime expiryDate, DateTime expirationDate)
{
// both values after 30.12.3000 00:00:00 --> same...
if (expiryDate.Day >= 30 && expiryDate.Month >= 12 && expiryDate.Year >= 3000 &&
expirationDate.Day >= 30 && expirationDate.Month >= 12 && expirationDate.Year >= 3000) { return false; }
return expiryDate.Ticks != expirationDate.Ticks;
}
public bool isMsdOpen(DateTime msdOpenDate)
{
return (msdOpenDate.Ticks > msdOpenTime);
}
public List<ExternalControlResult> GetPackagingUnitControlStatus(List<PackagingUnitLocation> packagingUnitLocations)
{
throw new NotImplementedException();
}
public List<ExternalControlResult> GetNewPackagingUnitData(List<PackagingUnitLocation> packagingUnitLocations)
{
throw new NotImplementedException();
}
#endregion
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.itac.mes.imsapi;
namespace com.itac.mes.imsapi.data
{
public class SmtContainer
{
public static string[] MAXIMAL_INFORMATION = new string[] { "MATERIAL_BIN_NUMBER", "EXPIRATION_DATE", "MATERIAL_BIN_DATE_CODE",
"MATERIAL_BIN_PART_NUMBER", "MATERIAL_BIN_STATE", "SUPPLIER_CHARGE_NUMBER", "DATE_CREATED",
"PART_COST", "PART_COST_BASE", "STORAGE_DESC", "STORAGE_NUMBER", "RECEIVING_NUMBER", "SUPPLIER_NAME", "SUPPLIER_NUMBER",
"CLASSIFICATION", "MSL_STATE", "MSL_LEVEL", "MSL_DRY_END_DATE", "MSL_OPEN_DATE", "HU_NUMBER",
"MATERIAL_BIN_QTY_ACTUAL", "MATERIAL_BIN_QTY_TOTAL"};
public static string[] MINIMAL_INFORMATION = new string[] { "MATERIAL_BIN_NUMBER", "EXPIRATION_DATE", "MATERIAL_BIN_STATE",
"MSL_STATE", "MSL_LEVEL", "MSL_DRY_END_DATE", "MSL_OPEN_DATE", "MATERIAL_BIN_QTY_ACTUAL" };
[ImsApiKey(Key = "MATERIAL_BIN_NUMBER")]
public string materialBinNumber { get; set; }
[ImsApiKey(Key = "MATERIAL_BIN_QTY_ACTUAL")]
public int materialBinQuantityActual = 0;
[ImsApiKey(Key = "MATERIAL_BIN_QTY_TOTAL")]
public int quantity = 0;
[ImsApiKey(Key = "ERROR_CODE")]
public int errorCode = 0;
[ImsApiKey(Key = "EXPIRATION_DATE")]
public DateTime expirationDate;
[ImsApiKey(Key = "DATE_CREATED")]
public DateTime dateCreated;
[ImsApiKey(Key = "MSL_DRY_END_DATE")]
public DateTime mslDryEndDate;
[ImsApiKey(Key = "MSL_OPEN_DATE")]
public DateTime mslOpenDate;
[ImsApiKey(Key = "MATERIAL_BIN_DATE_CODE")]
public string materialBinDateCode;
[ImsApiKey(Key = "MATERIAL_BIN_PART_NUMBER")]
public string materialBinPartNumber;
[ImsApiKey(Key = "MATERIAL_BIN_STATE")]
public string materialBinState;
[ImsApiKey(Key = "SUPPLIER_CHARGE_NUMBER")]
public string supplierChargeNumber;
[ImsApiKey(Key = "PART_COST")]
public string partCost;
[ImsApiKey(Key = "PART_COST_BASE")]
public string partCostBase;
[ImsApiKey(Key = "STORAGE_DESC")]
public string storageDesc;
[ImsApiKey(Key = "STORAGE_NUMBER")]
public string storageNumber;
[ImsApiKey(Key = "RECEIVING_NUMBER")]
public string receivingNumber;
[ImsApiKey(Key = "SUPPLIER_NAME")]
public string supplierName;
[ImsApiKey(Key = "SUPPLIER_NUMBER")]
public string supplierNumber;
[ImsApiKey(Key = "CLASSIFICATION")]
public string classification;
[ImsApiKey(Key = "MSL_STATE")]
public string mslState;
[ImsApiKey(Key = "MSL_LEVEL")]
public string mslLevel;
[ImsApiKey(Key = "HU_NUMBER")]
public string huNumber;
public int CompareTo(MaterialBinBooking obj)
{
if (materialBinNumber == null) return -1;
if (obj == null) return 1;
return materialBinNumber.CompareTo(obj.materialBinNumber);
}
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Itac.Oib
{
public interface IReceiver
{
void StartReceiver();
void StopReceiver();
}
}

View File

@@ -0,0 +1,456 @@
#region Namespace
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.ServiceProcess;
using System.Threading;
using com.itac.mes.tools;
using Itac.Oib;
using Asm.As.Oib.Client;
using com.itac.mes.imsapi.client.dotnet;
using com.itac.mes.imsapi.domain.container;
using Imsapi = com.itac.mes.imsapi.domain.container;
using System.Security.Principal;
using com.itac.mes.simm;
using com.itac.mes.imsapi;
#endregion
namespace com.itac.mes.proxy.winservice
{
public class WindowsService : ServiceBase
{
#region Fields
/// <summary>
/// Der Linienname ergibt sich aus der SetupCenter Konfiguration. Es darf nur eine Linie geben.
/// </summary>
private OibClient _oibClient;
private static List<tools.KeyValue> versionList;
private static IMSApiDotNet imsapi = null;
private IMSApiSessionValidationStruct sessValData = new IMSApiSessionValidationStruct();
private IMSApiSessionContextStruct newSessionContext = null;
private IIMSApi imsapiproxy = null;
#endregion
#region Static Methods
private static string GetVersionNr()
{
var asm = Assembly.GetExecutingAssembly();
var asmName = asm.GetName();
object[] attribs = asm.GetCustomAttributes(typeof(AssemblyProductAttribute), true);
string productName = String.Empty;
if (attribs.Length > 0)
{
var asmProduct = attribs[0] as AssemblyProductAttribute;
productName = asmProduct.Product;
}
string aVersion = String.Format("{1}.{2}.{3}.{4}",
productName, asmName.Version.Major, asmName.Version.Minor, asmName.Version.Build, asmName.Version.Revision);
string vers = String.Format("{0} - Version: {1}", productName, aVersion);
return (vers);
}
private static string GetFileVersionNr()
{
var asm = Assembly.GetExecutingAssembly();
object[] attribs = asm.GetCustomAttributes(typeof(AssemblyProductAttribute), true);
string productName = String.Empty;
var assembly = Assembly.GetExecutingAssembly();
if (attribs.Length > 0)
{
var asmProduct = attribs[0] as AssemblyProductAttribute;
productName = asmProduct.Product;
}
var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
// string version = fvi.ProductVersion;
versionList.Add(new tools.KeyValue() { key = productName, value = fvi.ProductVersion });
string version = String.Format("FileVersion: {1}", productName, fvi.ProductVersion);
String[] xVersion = fvi.Comments.Split();
String[] mesVersion = xVersion[3].Split('=');
versionList.Add(new tools.KeyValue() { key = mesVersion[0], value = mesVersion[1] });
String[] intfVersion = xVersion[4].Split('=');
versionList.Add(new tools.KeyValue() { key = intfVersion[0],value = intfVersion[1] });
return (version);
}
#endregion
/// <summary>
/// Public Constructor for WindowsService.
/// - Put all of your Initialization code here.
/// </summary>
public WindowsService()
{
ServiceName = Constants.SERVICE_NAME;
EventLog.Log = "EVENT_TYPE";
// These Flags set whether or not to handle that specific
// type of event. Set to true if you need it, false otherwise.
CanHandlePowerEvent = true;
CanHandleSessionChangeEvent = true;
CanPauseAndContinue = true;
CanShutdown = true;
CanStop = true;
}
/// <summary>
/// The Main Thread: This is where your Service is Run.
/// </summary>
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
if (e.IsTerminating)
{
object o = e.ExceptionObject;
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "### general exception handling ###");
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, o.ToString());
}
};
var service = new WindowsService();
#if (SERVICE)
ServiceBase.Run(service);
#else
service.OnStart(null);
Console.ReadLine();
service.OnStop();
#endif
}
/// <summary>
/// OnStart(): Put startup code here
/// - Start threads, get inital data, etc.
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
InitService();
base.OnStart(args);
}
/// <summary>
/// OnStop(): Put your stop code here
/// - Stop threads, set final data, etc.
/// </summary>
protected override void OnStop()
{
ShutdownService();
base.OnStop();
}
/// <summary>
/// OnShutdown(): Called when the System is shutting down
/// - Put code here when you need special handling
/// of code that deals with a system shutdown, such
/// as saving special data before shutdown.
/// </summary>
protected override void OnShutdown()
{
ShutdownService();
base.OnShutdown();
}
/// <summary>
/// Dieser Adapter übernimmt die Steuerung der Subscriptions und der Endpoints
/// </summary>
private StatisticWorker statisticWorker;
private Thread statisticThread;
private void InitService()
{
// Ausgabe hilfe für xml-Messages
var config = new AppSettingsReader();
try
{
#if (SERVICE)
TraceListener eventLogTraceListener = new EventLogTraceListener(Constants.SERVICE_NAME);
eventLogTraceListener.Filter = new EventTypeFilter(SourceLevels.Information);
LogHandler.addListener(eventLogTraceListener);
#endif
// Der Port an dem der Adapter auf eingehende Verbindungen des iTAC DataInterface lauscht
Asm.As.Oib.Client.Configuration.OibClientConfiguration oibClientconfiguration = new Asm.As.Oib.Client.Configuration.OibClientConfiguration();
// PRE: _oibClient = new OibClient("iTac", "OibAdapter", oibCoreComuputerName, configuredLineFullPath);
oibClientconfiguration.ApplicationName = "SIMMApplication";
oibClientconfiguration.CompanyName = "iTac";
// TODO is not necessary to set
oibClientconfiguration.EventNotificationProtocol = new Asm.As.Oib.Client.Configuration.EventNotificationProtocol();
oibClientconfiguration.OibClientMode = Asm.As.Oib.Client.Configuration.OibClientMode.MaterialManager;
oibClientconfiguration.TcpPortSharingEnabled = true;
// TODO: check this value
oibClientconfiguration.UnsubscribeCoreEventsOnShutdown = true;
var clusterNodes = (String)config.GetValue("itac.artes.clusterNodes", typeof(String));
var stationNumber = (String)config.GetValue("stationNumber", typeof(String));
var client = (String)config.GetValue("client", typeof(String));
var transactionCode = (int)config.GetValue("transactionCode", typeof(int));
oibClientconfiguration.FactoryElementPath = (String)config.GetValue("factoryElementPathMes", typeof(String));
// diese Werte werden alle benötigt...
oibClientconfiguration.CoreComputerName = (String)config.GetValue("OIBCoreHostName", typeof(String));
oibClientconfiguration.SetupCenterExternalControlCallbackPort = (int)config.GetValue("SetupCenterExternalControlPort", typeof(int));
// check values for those 3 settings (off, MES, SiMM);
ConfigCode quantityMaster = ConfigCode.OFF;
ConfigCode mslMaster = ConfigCode.OFF;
ConfigCode expirationMaster = ConfigCode.OFF;
try
{
quantityMaster = GetCode((String)config.GetValue("QuantityMaster", typeof(String)), "QuantityMaster");
mslMaster = GetCode((String)config.GetValue("MSLMaster", typeof(String)), "MSLMaster");
expirationMaster = GetCode((String)config.GetValue("ExpirationMaster", typeof(String)), "ExpirationMaster");
}
catch (ArgumentException ae)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, ae.Message);
return;
}
string sEmptyContainerCheckInterval = (string)config.GetValue("emptyContainerCheckInterval", typeof(string));
TimeSpan emptyContainerCheckInterval = new TimeSpan(0);
try
{
emptyContainerCheckInterval = TimeSpan.Parse(sEmptyContainerCheckInterval);
}
catch (FormatException)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "invalid value " + sEmptyContainerCheckInterval + " for configParameter emptyContainerCheckInterval");
return;
}
catch (OverflowException)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "invalid value " + sEmptyContainerCheckInterval + " for configParameter emptyContainerCheckInterval");
return;
}
if (emptyContainerCheckInterval.Ticks == 0)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "checking MES for empty containers switched OFF by configuration value");
}
else
{
if (emptyContainerCheckInterval.TotalSeconds < ContainerCheckThread.MIN_INTERVAL_SECONDS)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "minimum value for checking MES for empty containers is " + ContainerCheckThread.MIN_INTERVAL_SECONDS
+ " seconds, but configured is " + emptyContainerCheckInterval.ToString());
return;
}
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "checking MES for empty containers " + emptyContainerCheckInterval.ToString());
// create and start appropriate thread
}
// check that the process is started as administrator or end process with message
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "");
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Insufficient privileges!");
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "This process needs to be started with administrative privileges.");
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Right click on the executable file and select \"Run As Administrator\"");
return;
}
versionList = new List<tools.KeyValue>();
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("iTAC.SIMM.Application"));
LogHandler.log(Constants.LOGGER, TraceEventType.Information, GetVersionNr() + " / " + GetFileVersionNr());
IMSApiDotNet.setProperty("itac.appid", "iTAC_SIMM_Application");
IMSApiDotNet.setProperty("itac.artes.clusternodes", clusterNodes);
imsapi = IMSApiDotNet.loadLibrary();
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("IMS API"));
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "start Initializing IMS API " + clusterNodes);
int result = imsapi.imsapiInit();
if (result != IMSApiDotNetConstants.RES_OK)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "IMS API initialization failed " + clusterNodes + ": " + result);
return;
}
// read values for 'in' and 'inout' arguments
sessValData.stationNumber = stationNumber;
sessValData.stationPassword = "";
sessValData.user = "";
sessValData.password = "";
sessValData.client = client;
sessValData.registrationType = "S";
sessValData.systemIdentifier = "iTAC.SIMM";
result = imsapi.regLogin(sessValData, out newSessionContext);
if (result != IMSApiDotNetConstants.RES_OK)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "IMS API regLogin failed: " + result);
return;
}
ImsApiProxy proxy = new ImsApiProxy(imsapi);
imsapiproxy = (IIMSApi)proxy.GetTransparentProxy();
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "IMS API initialized");
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in loadedAssemblies)
{
if (assembly.FullName.StartsWith("AsmApi"))
{
AssemblyProductAttribute adAttr = (AssemblyProductAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyProductAttribute));
versionList.Add(new tools.KeyValue() { key = "AsmApi", value = adAttr.Product });
Console.WriteLine("AsmApi" + adAttr.Product);
}
}
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("Simm Application Startup"));
_oibClient = new OibClient(oibClientconfiguration);
/// listener auf externalcontrol bauen
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("SetupCenterExternalControl"));
var oibSetupCenterExternalControlEvents = _oibClient.GetOibSetupCenterExternalControlEvents();
var setupCenterNotificationClient = _oibClient.GetSetupCenterNotificationClient();
SetupCenterExternalControlReceiver externalcontrolReceiver = new SetupCenterExternalControlReceiver(oibSetupCenterExternalControlEvents, imsapiproxy, newSessionContext,
stationNumber, transactionCode, quantityMaster, mslMaster, expirationMaster);
externalcontrolReceiver.StartReceiver();
// create and start appropriate thread
if (emptyContainerCheckInterval.TotalSeconds >= 10)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("iTAC.SiMM.Application startup container check thread"));
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "checking MES for empty containers interval: " + emptyContainerCheckInterval.ToString());
ContainerCheckThread ctt = new ContainerCheckThread(emptyContainerCheckInterval, imsapiproxy, newSessionContext, setupCenterNotificationClient, stationNumber);
ctt.Start();
}
try
{
HashSet<string> versionKeySet = new HashSet<string>();
versionKeySet.Add("ServiceLocator");
versionKeySet.Add("SIPLACE.SetupCenter.MaterialControl");
/* var serviceLocator = _oibClient.GetSubscriptionManagerClient();
var allServices = serviceLocator.GetAllServices();
for (int i = 0; i < allServices.Length; i++)
{
var sd = allServices[i];
if (versionKeySet.Contains(sd.ServiceName) && sd.Configuration != null)
{
versionList.Add(new KeyValue() { key = sd.ServiceName, value = sd.ServiceVersion });
}
}
*/
}
catch (Exception)
{
throw;
}
String currentPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "current path = " + currentPath);
var proxyVersions = _oibClient.GetOibProxyVersions();
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("SIMM Proxy Versions"));
foreach (var keyValuePair in proxyVersions)
{
if (!keyValuePair.Key.Equals("AsmApi"))
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, string.Format("{0,-50} {1,10}", keyValuePair.Key, keyValuePair.Value));
}
}
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("Statistic Thread"));
try
{
statisticWorker = new StatisticWorker();
statisticWorker.setVersionList(versionList);
statisticThread = new Thread(statisticWorker.DoWork);
statisticThread.Start();
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "Statistic thread started! ");
}
catch (Exception e)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Statistic thread NOT started!", e);
}
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("Initialization completed"));
}
catch (Exception e)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Initialization failed! " + e.Message, e);
}
}
private ConfigCode GetCode(string sCodeValue, string sParameterName)
{
foreach (ConfigCode configCode in Enum.GetValues(typeof(ConfigCode)))
{
if (configCode.ToString().Equals(sCodeValue.ToUpper()))
{
return configCode;
}
}
throw new ArgumentException("The value " + sCodeValue + " is invalid for the parameter " + sParameterName);
}
private string getHeadertext(string v)
{
String separator = "-----------------------------------------------------------------------";
if (separator.Length < v.Length)
{
return separator.Substring(0, 10) + " " + v;
}
else
{
return separator.Substring(0, 10) + " " + v + " " + separator.Substring(0, separator.Length - v.Length);
}
}
private void ShutdownService()
{
statisticWorker.RequestStop();
statisticThread.Join();
if (_oibClient != null)
_oibClient.Dispose();
}
}
}

View File

@@ -0,0 +1,57 @@
using System;
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.ServiceProcess;
using com.itac.mes.tools;
namespace com.itac.mes.proxy.winservice
{
[RunInstaller(true)]
public class WindowsServiceInstaller : Installer
{
/// <summary>
/// Public Constructor for WindowsServiceInstaller.
/// - Put all of your Initialization code here.
/// </summary>
public WindowsServiceInstaller()
{
ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();
ServiceInstaller serviceInstaller = new ServiceInstaller();
//# Service Account Information
serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
serviceProcessInstaller.Username = null;
serviceProcessInstaller.Password = null;
//# Service Information
serviceInstaller.DisplayName = "SERVICE_DESC";
serviceInstaller.StartType = ServiceStartMode.Automatic;
//# This must be identical to the WindowsService.ServiceBase name
//# set in the constructor of WindowsService.cs
serviceInstaller.ServiceName = Constants.SERVICE_NAME;
this.Installers.Add(serviceProcessInstaller);
this.Installers.Add(serviceInstaller);
}
public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
ServiceController controller = new ServiceController(Constants.SERVICE_NAME);
try
{
controller.Start();
}
catch (Exception e)
{
if (!EventLog.SourceExists(Constants.SERVICE_NAME))
{
EventLog.CreateEventSource(Constants.SERVICE_NAME, "EVENT_TYPE");
}
EventLog.WriteEntry(Constants.SERVICE_NAME, "@The service could not be started. Error: " + e.Message, EventLogEntryType.Error);
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
Version 3.2.0.1 (20161124)
----------------------------------------------------------------------------------------
- Initial Version
- no automatic registration of the endpoint for SiMM
- start as administrator required
- basic functionality adjusting material quantity

View File

@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<appSettings>
<!-- The name or the IP address of the OIB Core Host -->
<add key="OIBCoreHostName" value="192.168.5.51" />
<!-- define the factory element for the MES SiMM Application.
Find the value for this configuration in the ASM Studio - Factory Layout.
Typically use here the main area. -->
<add key="factoryElementPathMes" value="Enterprise:Site_327811073"/>
<!-- the port of the endpoint. please note that port sharing is not enabled;
every application MUST have it's own port
the resulting endpoint looks like this
http://host:port/iTAC.SIMMApplication/SetupCenterExtCrtl/SIMM
You may browse this port via a web browser and you will get an overview page
It is required to assign this endpoint manually to the Factory
-->
<add key="SetupCenterExternalControlPort" value="35331"/>
<!-- define to which server this iTAC.SIMM.Application should connect to -->
<add key="itac.artes.clusternodes" value="http://itacsv103:10080/mes"/>
<!-- define the client
this is required for registration of the process -->
<add key="client" value="01"/>
<!-- use this movement code for any material quantity change
because the client just provides the current filling level it is not possible to
distinguish between positive and negative movements -->
<add key="transactionCode" value="122" />
<!-- define which station number should be used to call IMSAPI for Material verification
a verification will fail if the station is not existent or not TR-licensed -->
<add key="stationNumber" value="01010010"/>
<!-- define which system leads for maintaining the quantities of containers
available values are off, MES, SIMM
see flows for description-->
<add key="QuantityMaster" value="off"/>
<!-- define which system leads for maintaining the msl-Values of containers
available values are off, MES, SIMM (not case-sensitive)
see flows for description-->
<add key="MSLMaster" value="SIMM"/>
<!-- define which system leads for maintaining the expiration of containers
available values are off, MES, SIMM (not case-sensitive)
see flows for description-->
<add key="ExpirationMaster" value="simm"/>
<!-- define the interval the application check s the MES for empty containers
and report them to the SiMM
Format: hr:mi:secs, invalid values are reported at start time
Option is disabled if value is 00:00:00 -->
<add key="emptyContainerCheckInterval" value="00:00:15"/>
<!-- optional parameters to enable/disable some features
by default this check is disabled!-->
<add key="mslLevelCheck" value="false"/>
</appSettings>
<log4net>
<appender name="LogFileAppenderFull" type="log4net.Appender.RollingFileAppender">
<file value=".\log\itac.simm.full.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<header value="" />
<footer value="" />
<conversionPattern value="%date{dd.MM.yyyy HH:mm:ss,f} %8.10c %-5p %m%n" />
</layout>
</appender>
<appender name="LogFileAppenderError" type="log4net.Appender.RollingFileAppender">
<file value=".\log\itac.simm.error.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="3" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="WARN" />
<levelMax value="FATAL" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<header value="" />
<footer value="" />
<conversionPattern value="%date{dd.MM.yyyy HH:mm:ss,f} %8.10c %-5p %m%n" />
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<header value="[Header]\r\n" />
<footer value="[Footer]\r\n" />
<conversionPattern value="%date{dd.MM.yyyy HH:mm:ss,f} %8.10c %-5p %m%n" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="FATAL" />
</filter>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppenderFull" />
<appender-ref ref="LogFileAppenderError" />
<appender-ref ref="ConsoleAppender" />
</root>
</log4net>
</configuration>

View File

@@ -0,0 +1,326 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using www.siplace.com.OIB._2008._05.SetupCenter.Contracts.Data;
using System.Globalization;
using com.itac.mes.simm;
using com.itac.mes.imsapi;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using com.itac.mes.imsapi.domain.container;
using com.itac.mes.imsapi.data;
namespace Itac.Oib.Tests
{
public class ImsApiMock : RealProxy
{
public ImsApiMock() : base(typeof(IIMSApi)) { }
private Dictionary<string, int> callCountDictionary = new Dictionary<string, int>();
public override IMessage Invoke(IMessage message)
{
// start der Methode
IMethodCallMessage methodMsg = (IMethodCallMessage)message;
if (!callCountDictionary.ContainsKey(methodMsg.MethodName))
{
callCountDictionary.Add(methodMsg.MethodName, 1);
}
else
{
callCountDictionary.Add(methodMsg.MethodName, callCountDictionary[methodMsg.MethodName] + 1);
}
object[] args = methodMsg.Args;
object returnValue = null;
if (methodMsg.MethodName.Equals("mlGetMaterialBinData"))
{
KeyValue callParam = ((KeyValue[])args[2])[0];
// Keys = "MATERIAL_BIN_NUMBER", "EXPIRATION_DATE", "MATERIAL_BIN_STATE", "MSL_STATE", "MSL_LEVEL", "MSL_DRY_END_DATE", "MSL_OPEN_DATE", "MATERIAL_BIN_QTY_ACTUAL"
if (callParam.value.Equals("000608"))
{
args[5] = new String[] { "000608", "32535212399000", "R", "C", "2a", "", "", "10.0" };
}
else if (callParam.value.Equals("000609"))
{
args[5] = new String[] { "000609", "0", "R", "O", "2a", "", "", "10.0" };
}
else if (callParam.value.Equals("000610"))
{
// expiration 2032.12.31
args[5] = new String[] { "000610", "1988060400000", "R", "O", "2a", "", "", "10.0" };
}
}
returnValue = 0;//
return new ReturnMessage(returnValue, args, 0, methodMsg.LogicalCallContext, methodMsg);
}
public int getCallCount(string methodName)
{
if (!callCountDictionary.ContainsKey(methodName)) { return 0; }
return callCountDictionary[methodName];
}
}
[TestClass()]
public class SetupCenterExternalControlReceiverTests
{
[TestMethod()]
public void GetNewPackagingUnitDataTest()
{
PackagingUnit pu = new PackagingUnit();
pu.UID = "outer";
pu.SplicedPackagingUnit = new PackagingUnit();
pu.SplicedPackagingUnit.UID = "spliced";
PackagingUnit spliced = pu.SplicedPackagingUnit;
spliced.SplicedPackagingUnit = new PackagingUnit();
spliced.SplicedPackagingUnit.UID = "last";
Dictionary<string, PackagingUnit> packagingUnitMap = new Dictionary<string, PackagingUnit>();
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, null, null, "", 201, ConfigCode.SIMM, ConfigCode.OFF, ConfigCode.OFF);
testee.deepAddUnit(pu, ref packagingUnitMap);
Assert.IsTrue(packagingUnitMap.ContainsKey("spliced"));
Assert.IsTrue(packagingUnitMap.ContainsKey("last"));
Assert.IsTrue(packagingUnitMap.ContainsKey("outer"));
}
[TestMethod()]
public void shouldMapValues()
{
PackagingUnit pu = new PackagingUnit();
pu.UID = "outer";
string[] materialBinUploadKeys = new String[] { "ERROR_CODE", "MATERIAL_BIN_NUMBER" };
string[] result = new string[20];
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, null, null, "", 201, ConfigCode.OFF, ConfigCode.OFF, ConfigCode.OFF);
testee.mapValues(pu, materialBinUploadKeys, ref result, 2);
Assert.AreEqual("0", result[2]);
Assert.AreEqual("outer", result[3]);
}
[TestMethod()]
public void shouldParseDoubleLanguageIndependent()
{
string v = "9950,0";
v = v.Replace(",", ".");
CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
Double d = Double.Parse(v, culture);
Assert.AreEqual(9950.0, d);
}
[TestMethod()]
public void shouldReturnMaxDateString()
{
DateTime newDate = new DateTime(4000, 12, 3, 14, 23, 55, DateTimeKind.Utc);
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, null, null, "", 201, ConfigCode.OFF, ConfigCode.OFF, ConfigCode.OFF);
Assert.AreEqual("32535212399000", testee.getImsApiDateString(newDate));
}
[TestMethod()]
public void shouldReturnMinDateString()
{
DateTime newDate = new DateTime(1969, 12, 3, 02, 23, 55, DateTimeKind.Utc);
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, null, null, "", 201, ConfigCode.OFF, ConfigCode.OFF, ConfigCode.OFF);
Assert.AreEqual("0", testee.getImsApiDateString(newDate));
}
[TestMethod()]
public void shouldReturnCorrectDateString()
{
// Fri Nov 25 2016 10:46:25
DateTime newDate = new DateTime(2016, 11, 25, 09, 46, 25, DateTimeKind.Utc);
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, null, null, "", 201, ConfigCode.OFF, ConfigCode.OFF, ConfigCode.OFF);
Assert.AreEqual("1480067185000", testee.getImsApiDateString(newDate));
}
[TestMethod()]
public void shouldReturnClosedContainer()
{
//prepare
PackagingUnit pu = new PackagingUnit();
pu.UID = "000608";
pu.ExpiryDate = DateTime.MinValue.ToUniversalTime();
pu.ConsumptionDate = DateTime.MinValue.ToUniversalTime();
pu.ManufacturerDate = DateTime.MinValue.ToUniversalTime();
pu.LastProductionDate = DateTime.MinValue.ToUniversalTime();
pu.MsdOpenDate = DateTime.MinValue.ToUniversalTime();
PackagingUnitLocation location = new PackagingUnitLocation();
location.PackagingUnit = pu;
ImsApiMock proxy = new ImsApiMock();
IIMSApi imsApiMock = (IIMSApi)proxy.GetTransparentProxy();
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, imsApiMock, null, "", 201,
ConfigCode.OFF, ConfigCode.OFF, ConfigCode.OFF);
PackagingUnitLocation[] packagingUnitLocations = new PackagingUnitLocation[] { location };
// call
ExternalControlResult[] result = testee.GetPackagingUnitControlStatus(packagingUnitLocations);
Assert.AreEqual(DateTime.MinValue, result[0].PackagingUnit.MsdOpenDate);
}
[TestMethod()]
public void shouldReturnOpenedContainer()
{
//prepare
PackagingUnit pu = new PackagingUnit();
pu.UID = "000609";
pu.ExpiryDate = DateTime.MinValue.ToUniversalTime();
pu.ConsumptionDate = DateTime.MinValue.ToUniversalTime();
pu.ManufacturerDate = DateTime.MinValue.ToUniversalTime();
pu.LastProductionDate = DateTime.MinValue.ToUniversalTime();
pu.MsdOpenDate = DateTime.MinValue.ToUniversalTime();
PackagingUnitLocation location = new PackagingUnitLocation();
location.PackagingUnit = pu;
ImsApiMock proxy = new ImsApiMock();
IIMSApi imsApiMock = (IIMSApi)proxy.GetTransparentProxy();
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, imsApiMock, null, "", 201,
ConfigCode.OFF, ConfigCode.SIMM, ConfigCode.SIMM);
PackagingUnitLocation[] packagingUnitLocations = new PackagingUnitLocation[] { location };
// call
ExternalControlResult[] result = testee.GetPackagingUnitControlStatus(packagingUnitLocations);
Assert.AreEqual(DateTime.MinValue, result[0].PackagingUnit.MsdOpenDate);
Assert.AreEqual(DateTime.MinValue, result[0].PackagingUnit.ExpiryDate);
// expected is no adjustment of the material bin data in the mes
Assert.AreEqual(0, proxy.getCallCount("mlChangeMaterialBinData"));
}
[TestMethod()]
public void shouldAdjustContainerExpirationInMES()
{
//prepare
PackagingUnit pu = new PackagingUnit();
pu.UID = "000610";
pu.ExpiryDate = new DateTime(2000, 12, 31).ToUniversalTime();
pu.ConsumptionDate = DateTime.MinValue.ToUniversalTime();
pu.ManufacturerDate = DateTime.MinValue.ToUniversalTime();
pu.LastProductionDate = DateTime.MinValue.ToUniversalTime();
pu.MsdOpenDate = DateTime.MinValue.ToUniversalTime();
PackagingUnitLocation location = new PackagingUnitLocation();
location.PackagingUnit = pu;
ImsApiMock proxy = new ImsApiMock();
IIMSApi imsApiMock = (IIMSApi)proxy.GetTransparentProxy();
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, imsApiMock, null, "", 201,
ConfigCode.OFF, ConfigCode.SIMM, ConfigCode.SIMM);
PackagingUnitLocation[] packagingUnitLocations = new PackagingUnitLocation[] { location };
// call
ExternalControlResult[] result = testee.GetPackagingUnitControlStatus(packagingUnitLocations);
Assert.AreEqual(DateTime.MinValue, result[0].PackagingUnit.MsdOpenDate);
// expected is no adjustment of the material bin data in the mes
Assert.AreEqual(1, proxy.getCallCount("mlChangeMaterialBinData"), "mlChangeMaterialBinData nicht aufgerufen");
Assert.AreEqual(1, proxy.getCallCount("mslStopObjectExpiration"), "mslStopObjectExpiration nicht aufgerufen");
}
[TestMethod()]
public void shouldNotTakeOverQuantity()
{
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, null, null, "", 201, ConfigCode.OFF, ConfigCode.OFF, ConfigCode.OFF);
SmtContainer container = new SmtContainer();
container.materialBinQuantityActual = 100;
PackagingUnit packagingUnit = new PackagingUnit();
packagingUnit.Quantity = 50;
LinkedList<MaterialBinBooking> updateQtyList = new LinkedList<MaterialBinBooking>();
testee.adjustQuantity(ConfigCode.OFF, ref container, ref packagingUnit, ref updateQtyList);
Assert.AreEqual(50, packagingUnit.Quantity);
Assert.AreEqual(0, updateQtyList.Count);
}
/* [TestMethod()]
public void shouldTakeOverMesExpiration()
{
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, null, null, "", 201, ConfigCode.OFF, ConfigCode.OFF, ConfigCode.OFF);
SmtContainer container = new SmtContainer();
container.expirationDate = new DateTime(2017, 01, 14, 12, 34, 55, DateTimeKind.Utc);
PackagingUnit packagingUnit = new PackagingUnit();
packagingUnit.ExpiryDate = new DateTime(2012, 01, 14, 12, 34, 55, DateTimeKind.Utc);
LinkedList<MaterialBinBooking> updateQtyList = new LinkedList<MaterialBinBooking>();
Object p = new object()
{ int mlChangeMaterialBinData(IMSApiSessionContextStruct sessionContext, string stationNumber, string materialBinNumber, KeyValue[] materialBinDataUploadValues)
{
return 0;
}
};
ExternalControlResult result = new ExternalControlResult();
IIMSApi imsapi = (IIMSApi)p;
testee.adjustExpiration(ConfigCode.MES, ref container, ref packagingUnit, ref imsapi, ref result);
Assert.AreEqual(2017, packagingUnit.ExpiryDate.Year);
}
*/
/*
[TestMethod()]
public void shouldTakeOverQuantity()
{
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, null, null, "", 201, ConfigCode.OFF, ConfigCode.OFF, ConfigCode.OFF);
SmtContainer container = new SmtContainer();
container.materialBinQuantityActual = 100;
PackagingUnit packagingUnit = new PackagingUnit();
packagingUnit.Quantity = 50;
LinkedList<MaterialBinBooking> updateQtyList = new LinkedList<MaterialBinBooking>();
testee.adjustQuantity(ConfigCode.SIMM, ref container, ref packagingUnit, ref updateQtyList);
Assert.AreEqual(1, updateQtyList.Count);
// mes setzt Gebinde auf Menge 50 (Menge der ASM-Pack-Unit
Assert.AreEqual(50, updateQtyList.First.Value.materialBinQuantityActual);
}
[TestMethod()]
public void shouldNotTakeOverQuantity()
{
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, null, null, "", 201, ConfigCode.OFF, ConfigCode.OFF, ConfigCode.OFF);
SmtContainer container = new SmtContainer();
container.materialBinQuantityActual = 100;
PackagingUnit packagingUnit = new PackagingUnit();
packagingUnit.Quantity = 50;
LinkedList<MaterialBinBooking> updateQtyList = new LinkedList<MaterialBinBooking>();
testee.adjustQuantity(ConfigCode.OFF, ref container, ref packagingUnit, ref updateQtyList);
Assert.AreEqual(50, packagingUnit.Quantity);
Assert.AreEqual(0, updateQtyList.Count);
}
*/
[TestMethod()]
public void shouldAcceptAsSameExpirationDate()
{
SetupCenterExternalControlReceiver testee = new SetupCenterExternalControlReceiver(null, null, null, "", 201, ConfigCode.OFF, ConfigCode.OFF, ConfigCode.OFF);
Assert.IsFalse(testee.expirationDateDifferent(new DateTime(3000, 12, 30, 4, 0, 0), new DateTime(3000, 12, 31, 0, 0, 0)));
}
}
}

View File

@@ -0,0 +1,17 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace com.itac.mes.imsapi.data.Tests
{
[TestClass()]
public class SmtContainerTests
{
[TestMethod()]
public void CompareToTest()
{
string[] resultValues = new string[] { "MATERIAL_BIN_NUMBER", "0000", "O", "O", "2a", "1234", "4567", "3000" };
SmtContainer knownContainer = new ImsApiMapTool<SmtContainer>().getStruct(typeof(SmtContainer), SmtContainer.MINIMAL_INFORMATION, resultValues);
Assert.AreEqual("MATERIAL_BIN_NUMBER", knownContainer.materialBinNumber);
}
}
}