initialize
This commit is contained in:
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
@@ -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>
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user