internal static void UpdatePosition(UserRegistration user) { /* * 1. fetch all positions that the user currently have * 2. compare positions from organisation with the positions in the registration, using the following rules * a) a position is a "match" if it points to the same unit (and no two positions can point to the same unit), or if it matches on UUID * b) a position should be updated if the name/shortKey/ou-pointer has been changed * c) a position should be removed if it no longer exist in the registration, but does in organisation * d) a position should be added, if it exists in the registration, but not in organisation */ // fetch all the users existing positions List <FiltreretOejebliksbilledeType> unitRoles = FindUnitRolesForUser(user.Uuid); // loop through roles found in organisation, and find those that must be updated, and those that must be deleted foreach (FiltreretOejebliksbilledeType unitRole in unitRoles) { RegistreringType1 existingRoleRegistration = unitRole.Registrering[0]; if (existingRoleRegistration.RelationListe.TilknyttedeEnheder.Length != 1) { log.Warn("User '" + user.Uuid + "' has an existing position in Organisation with " + existingRoleRegistration.RelationListe.TilknyttedeEnheder.Length + " associated OrgUnits"); continue; } // figure out everything relevant about the position object in Organisation EgenskabType latestProperty = StubUtil.GetLatestProperty(existingRoleRegistration.AttributListe.Egenskab); string existingRoleUuid = unitRole.ObjektType.UUIDIdentifikator; string existingRoleOUUuid = existingRoleRegistration.RelationListe.TilknyttedeEnheder[0].ReferenceID.Item; string existingRoleName = latestProperty.FunktionNavn; string existingRoleShortKey = latestProperty.BrugervendtNoegleTekst; bool found = false; foreach (DTO.V1_1.Position position in user.Positions) { // if the UUID of the function is controlled by the local system, the pointer to the OU could be changed, // so we also need to check for equality on the UUID of the function itself if (existingRoleUuid.Equals(position.Uuid) || (position.Uuid == null && existingRoleOUUuid.Equals(position.OrgUnitUuid))) { if (!existingRoleOUUuid.Equals(position.OrgUnitUuid) || // user has moved to a different OU (existingRoleName == null || !existingRoleName.Equals(position.Name)) || // the users title has changed (null check deals with bad GUI data) (position.ShortKey != null && existingRoleShortKey.Equals(position.ShortKey))) // there is a new ShortKey for the position { organisationFunktionStub.Ret(new OrgFunctionData() { Uuid = existingRoleUuid, ShortKey = (position.ShortKey != null) ? position.ShortKey : existingRoleShortKey, Name = position.Name, FunctionTypeUuid = UUIDConstants.ORGFUN_POSITION, OrgUnits = new List <string>() { position.OrgUnitUuid }, Users = new List <string>() { user.Uuid }, Timestamp = user.Timestamp }, UpdateIndicator.NONE, UpdateIndicator.COMPARE, UpdateIndicator.NONE); } found = true; break; } } if (!found) { organisationFunktionStub.Deactivate(existingRoleUuid, user.Timestamp); } } // loop through all roles found in the local registration, and create all those that do not exist in Organisation foreach (DTO.V1_1.Position position in user.Positions) { bool found = false; foreach (FiltreretOejebliksbilledeType unitRole in unitRoles) { RegistreringType1 existingRoleRegistration = unitRole.Registrering[0]; if (existingRoleRegistration.RelationListe.TilknyttedeEnheder.Length != 1) { log.Warn("User '" + user.Uuid + "' has an existing position in Organisation with " + existingRoleRegistration.RelationListe.TilknyttedeEnheder.Length + " associated OrgUnits"); continue; } string existingRoleUuid = unitRole.ObjektType.UUIDIdentifikator; string existingRoleOUUuid = existingRoleRegistration.RelationListe.TilknyttedeEnheder[0].ReferenceID.Item; if (existingRoleUuid.Equals(position.Uuid) || (position.Uuid == null && existingRoleOUUuid.Equals(position.OrgUnitUuid))) { found = true; } } if (!found) { organisationFunktionStub.Importer(new OrgFunctionData() { Uuid = position.Uuid, ShortKey = position.ShortKey, Name = position.Name, FunctionTypeUuid = UUIDConstants.ORGFUN_POSITION, OrgUnits = new List <string>() { position.OrgUnitUuid }, Users = new List <string>() { user.Uuid }, Timestamp = user.Timestamp }); } } }
/// <summary> /// Чтение приращений (показаний) /// </summary> /// <param name="fromTime"></param> /// <param name="typeQuery"></param> /// <param name="typeInc"></param> /// <param name="aplus"></param> /// <param name="aminus"></param> /// <param name="rplus"></param> /// <param name="rminus"></param> /// <param name="depth"></param> /// <param name="deepSyncTime"></param> /// <param name="tariff"> /// Добавлена поддержка чтения тарифов для показаний, т.к. эту величину нельзя расчитать. /// </param> static internal void ReadInc( QueryInfo info, DateTimeZone fromTime, TypeQuery typeQuery, TypeInc typeInc, TagDef aplus, TagDef aminus, TagDef rplus, TagDef rminus, int depth, DateTimeUtc deepSyncTime, ETariff tariff = ETariff.NoTariff) { //Если в гране нет данных то дальше этой даты записываем что нельзя востонавить bool fillBadNoRestore = false; int itemNum = 0; OperationResult oper = new OperationResult(Quality.Bad); var holes = info.GetHoles(typeInc, fromTime, depth, deepSyncTime, new[] { aplus }); var reversedHoles = holes.Reverse(); foreach (var item in reversedHoles) { itemNum++; Energy read = null; OperationResult res = OperationResult.Bad; if (fillBadNoRestore) { read = new Energy(0, 0, 0, 0); oper = new OperationResult(Quality.BadNoRestore); } else if (info.Session.BeginOperation()) { if (DataBusSetting.StubData) //STUBDATA-> { read = new Energy(StubUtil.Int32(500), StubUtil.Int32(600), StubUtil.Int32(700), StubUtil.Int32(800)); oper = new OperationResult(Quality.Good); } else { switch (typeQuery) { #region (case TypeQuery.SlicesEnergy:) case TypeQuery.SlicesEnergy: if (!info.IsHalfHourInterval) { oper = new OperationResult(Quality.Bad, "HalfHour Interval is incorrect!"); } else { // только для версий СЕ102 S7, R8, CE301M S31, R33 // версии CE102 S6, R5 не поддерживают архив получасов oper = info.Request.TryReadSlicesEnergy( info.DataBus, info.Cs.Psw, info.Session.TimeDevice, SlicesQuery.From(item, info.Cs.Address), out read); read.Calc(info.DeviceKoef); } break; #endregion #region (case TypeQuery.Counter:) case TypeQuery.Counter: oper = info.Request.TryReadCounter( info.DataBus, info.Cs.Psw, typeInc, RequestIndex.From(item, typeInc, info.Cs.Address, true), tariff, out read); read.Calc(info.DeviceKoef); break; #endregion /*#region (case TypeQuery.Power3min:) * case TypeQuery.Power3min: * AvPowerIndex pi; * oper = info.Request.TryReadAvPower3min( * info.DataBus, * info.Session.TimeDevice, * info.Session.Zone, * RequestIndex.From(item, typeInc, info.Cs.Address, false), * item, * out pi); * if (oper.IsGood) * read = pi.Power.ToEnergy(20); * break; #endregion*/ } //Может возникать ситуация когда на компе уже наступило время опроса а на счетчике нет и будет возвращен блок поврежден //TODO if ((itemNum < 3) && (oper.Quality == Quality.BadNoRestore)) oper.Quality = Quality.Bad; } /*if ((!oper.IsGood) && (oper.Code == 2)) * { * if (info.Session.OpenData.NewDevice != ChangeDeviceInfo.None) * info.LogWarn(SR.NOT_PARAM, info.DisplayName, aplus.AccountKind, aplus.Discrete, aplus.DiscreteValue); * info.Session.EndOperation(OperationResult.Good); * break; //Неизвестная функция не подерживаемая версией устройства * }*/ info.Session.EndOperation(oper); if (!oper.IsGood) { read = new Energy(0, 0, 0, 0); info.DataBus.DiscardInBuffer(); } if (oper.Quality == Quality.BadNoRestore) { fillBadNoRestore = true; //заполним все полохими не востанавливаемыми } } else { break; } info.Storage.WriteTagsValue( HW(oper.Quality, read.Aplus, item, aplus), HW(Quality.Bad, read.Aminus, item, aminus), HW(Quality.Bad, read.Rplus, item, rplus), HW(Quality.Bad, read.Rminus, item, rminus)); if (info.Log.Trace.IsOn(2)) { var sb = new StringBuilder(); sb.AppendFormat("Read from [{0}] {1} {2}", item, typeInc, oper.Quality); if (typeQuery != TypeQuery.SlicesEnergy) { sb.Append(" " + typeQuery); } if (!oper.IsGood) { sb.AppendFormat(". Error: {0}", oper.ErrorMsg); info.Log.Trace.Error(2, sb.ToString()); } else { sb.AppendFormat(". A+: {0}, A-: {1}, R+: {2}, R-: {3}", read.Aplus, read.Aminus, read.Rplus, read.Rminus); info.Log.Trace.Info(2, sb.ToString()); } } } }
internal static void UpdatePosition(UserRegistration user) { /* * 1. fetch all positions that the user currently have * 2. compare positions from organisation with the positions in the registration, using the following rules * a) a position is a "match" if it points to the same unit (yes, this is an issue for the users with multiple positions in the same OU, luckily those are few) * b) a position should be updated if the name/ou-pointer has been changed * c) a position should be removed if it no longer exist in the registration, but does in organisation * d) a position should be added, if it exists in the registration, but not in organisation */ // fetch all the users existing positions List <FiltreretOejebliksbilledeType> unitRoles = FindUnitRolesForUser(user.Uuid); List <Position> copyOfUserPositions = new List <Position>(user.Positions); // loop through roles found in organisation, and find those that must be updated, and those that must be deleted foreach (FiltreretOejebliksbilledeType unitRole in unitRoles) { RegistreringType1 existingRoleRegistration = unitRole.Registrering[0]; if (existingRoleRegistration.RelationListe.TilknyttedeEnheder.Length != 1) { log.Warn("User '" + user.Uuid + "' has an existing position in Organisation with " + existingRoleRegistration.RelationListe.TilknyttedeEnheder.Length + " associated OrgUnits"); continue; } // figure out everything relevant about the position object in Organisation EgenskabType latestProperty = StubUtil.GetLatestProperty(existingRoleRegistration.AttributListe.Egenskab); string existingRoleUuid = unitRole.ObjektType.UUIDIdentifikator; string existingRoleOUUuid = existingRoleRegistration.RelationListe.TilknyttedeEnheder[0].ReferenceID.Item; string existingRoleName = latestProperty.FunktionNavn; string existingRoleShortKey = latestProperty.BrugervendtNoegleTekst; bool found = false; for (int i = copyOfUserPositions.Count - 1; i >= 0; i--) { Position position = copyOfUserPositions[i]; if (existingRoleOUUuid.Equals(position.OrgUnitUuid)) { // update if needed if (string.Compare(existingRoleName, position.Name) != 0) { organisationFunktionStub.Ret(new OrgFunctionData() { Uuid = existingRoleUuid, ShortKey = existingRoleShortKey, Name = position.Name, FunctionTypeUuid = UUIDConstants.ORGFUN_POSITION, OrgUnits = new List <string>() { position.OrgUnitUuid }, Users = new List <string>() { user.Uuid }, Timestamp = user.Timestamp }, UpdateIndicator.NONE, UpdateIndicator.COMPARE, UpdateIndicator.NONE); // copy value to read data, so we can use it for comparison below when deciding what to create latestProperty.FunktionNavn = position.Name; } // ensure that the updated positions i no longer in the copied list, so multiple positions // in the same OU, will not hit the same source-position copyOfUserPositions.RemoveAt(i); found = true; break; } } if (!found) { organisationFunktionStub.Deactivate(existingRoleUuid, user.Timestamp); } } // refresh copy of positions var copyOfRemotePositions = new List <FiltreretOejebliksbilledeType>(unitRoles); // loop through all roles found in the local registration, and create all those that do not exist in Organisation foreach (var position in user.Positions) { bool found = false; for (int i = copyOfRemotePositions.Count - 1; i >= 0; i--) { var unitRole = copyOfRemotePositions[i]; RegistreringType1 existingRoleRegistration = unitRole.Registrering[0]; if (existingRoleRegistration.RelationListe.TilknyttedeEnheder.Length != 1) { log.Warn("User '" + user.Uuid + "' has an existing position in Organisation with " + existingRoleRegistration.RelationListe.TilknyttedeEnheder.Length + " associated OrgUnits"); continue; } string existingRoleOUUuid = existingRoleRegistration.RelationListe.TilknyttedeEnheder[0].ReferenceID.Item; string existingFunctionName = existingRoleRegistration.AttributListe.Egenskab[0].FunktionNavn; if (existingRoleOUUuid.Equals(position.OrgUnitUuid) && string.Compare(existingFunctionName, position.Name) == 0) { // to make sure we can add new positions within the same OU as existing positions, we // remove existing ones, one at a time, so we do not match twice copyOfRemotePositions.RemoveAt(i); found = true; } } if (!found) { organisationFunktionStub.Importer(new OrgFunctionData() { Uuid = IdUtil.GenerateUuid(), ShortKey = IdUtil.GenerateShortKey(), Name = position.Name, FunctionTypeUuid = UUIDConstants.ORGFUN_POSITION, OrgUnits = new List <string>() { position.OrgUnitUuid }, Users = new List <string>() { user.Uuid }, Timestamp = user.Timestamp }); } } }