PartnerDepot API, SignalRTags fixes, and test for duplicates
- Added PartnerDepot CRUD API to IFruitBankDataControllerCommon and FruitBankSignalRClient. - Fixed Partner entity association to ShippingDocument.PartnerId. - Changed EkaerHistory to sealed, added ForeignKey, IsOutgoing, Created. - Exposed GetEkaerHistoriesByForeignKey in SignalRTags. - Fixed SignalRTags usage in ShippingDocument queries. - Implemented ProductDtoTableItem deserialization workaround. - Added unit test to detect duplicate SignalRTags constant values.
This commit is contained in:
parent
0083a7bd6e
commit
3b22b07d02
|
|
@ -11,7 +11,7 @@ namespace FruitBank.Common.Entities;
|
|||
[Table(Name = FruitBankConstClient.EkaerHistoryDbTableName)]
|
||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.EkaerHistoryDbTableName)]
|
||||
|
||||
public abstract class EkaerHistory: MgEntityBase, ITimeStampInfo
|
||||
public sealed class EkaerHistory: MgEntityBase, ITimeStampInfo
|
||||
{
|
||||
public int ForeignKey { get; set; }
|
||||
public bool IsOutgoing { get; set; }
|
||||
|
|
|
|||
|
|
@ -11,6 +11,6 @@ namespace FruitBank.Common.Entities;
|
|||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.PartnerDbTableName)]
|
||||
public sealed class Partner : PartnerBase, IPartner
|
||||
{
|
||||
[Association(ThisKey = nameof(Id), OtherKey = nameof(ShippingDocument.ShippingId), CanBeNull = true)]
|
||||
[Association(ThisKey = nameof(Id), OtherKey = nameof(ShippingDocument.PartnerId), CanBeNull = true)]
|
||||
public List<ShippingDocument>? ShippingDocuments { get; set; }
|
||||
}
|
||||
|
|
@ -20,6 +20,14 @@ public interface IFruitBankDataControllerCommon
|
|||
public Task<Partner?> UpdatePartner(Partner partner);
|
||||
#endregion Partner
|
||||
|
||||
#region PartnerDepot
|
||||
public Task<List<PartnerDepot>?> GetPartnerDepots();
|
||||
public Task<PartnerDepot?> GetPartnerDepotById(int id);
|
||||
public Task<List<PartnerDepot>?> GetPartnerDepotsByPartnerId(int partnerId);
|
||||
public Task<PartnerDepot?> AddPartnerDepot(PartnerDepot partnerDepot);
|
||||
public Task<PartnerDepot?> UpdatePartnerDepot(PartnerDepot partnerDepot);
|
||||
#endregion PartnerDepot
|
||||
|
||||
#region CargoPartner
|
||||
public Task<List<CargoPartner>?> GetCargoPartners();
|
||||
public Task<CargoPartner?> GetCargoPartnerById(int id);
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ public class SignalRTags : AcSignalRTags
|
|||
|
||||
public const int GetEkaerHistories = 185;
|
||||
public const int GetEkaerHistoryById = 186;
|
||||
//public const int GetEkaerHistoriesByForeignKey = 187;
|
||||
public const int GetEkaerHistoriesByForeignKey = 187;
|
||||
public const int AddEkaerHistory = 188;
|
||||
public const int UpdateEkaerHistory = 189;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
using System.Reflection;
|
||||
using FruitBank.Common.SignalRs;
|
||||
|
||||
namespace FruitBankHybrid.Shared.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public sealed class SignalRTagsTests
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="SignalRTags"/> értékei a drót-protokoll azonosítói: két azonos értékű
|
||||
/// konstans (jellemzően copy-paste után) némán másik endpointra irányítaná a hívást.
|
||||
/// A kézi számkiosztás szándékos (stabil szerződés), ez a teszt csak alá feszít egy hálót:
|
||||
/// kibukik a duplikátumon, és megnevezi a vétkes konstansokat.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Csak a <see cref="SignalRTags"/>-ben DEKLARÁLT konstansokat vizsgálja (<c>DeclaredOnly</c>) —
|
||||
/// ide ír a fejlesztő kézzel. A framework-ős <c>AcSignalRTags</c>-szal való átfedés
|
||||
/// ellenőrzéséhez <c>BindingFlags.FlattenHierarchy</c> kellene.
|
||||
/// </remarks>
|
||||
[TestMethod]
|
||||
public void SignalRTags_HasNoDuplicateValues()
|
||||
{
|
||||
var tags = typeof(SignalRTags)
|
||||
.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)
|
||||
.Where(f => f.IsLiteral && f.FieldType == typeof(int))
|
||||
.Select(f => (f.Name, Value: (int)f.GetRawConstantValue()!))
|
||||
.ToList();
|
||||
|
||||
var duplicates = tags
|
||||
.GroupBy(t => t.Value)
|
||||
.Where(g => g.Count() > 1)
|
||||
.Select(g => $" {g.Key} = {string.Join(", ", g.Select(t => t.Name))}")
|
||||
.ToList();
|
||||
|
||||
Assert.AreEqual(0, duplicates.Count, $"Több SignalRTag ugyanazt az értéket kapta:{Environment.NewLine}{string.Join(Environment.NewLine, duplicates)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -70,6 +70,8 @@ public class ProductDtoTable(FruitBankSignalRClient fruitBankSignalRClient) : Ac
|
|||
|
||||
//Clear();
|
||||
this.Replace(items);
|
||||
//this.Replace(items.Cast<ProductDtoTableItem>());
|
||||
|
||||
//foreach (var productDto in items)
|
||||
//{
|
||||
// this.UpdateCollection(productDto, false);
|
||||
|
|
|
|||
|
|
@ -66,6 +66,14 @@ namespace FruitBankHybrid.Shared.Services.SignalRs
|
|||
public Task<Partner?> UpdatePartner(Partner partner) => PostDataAsync(SignalRTags.UpdatePartner, partner);
|
||||
#endregion Partner
|
||||
|
||||
#region PartnerDepot
|
||||
public Task<List<PartnerDepot>?> GetPartnerDepots() => GetAllAsync<List<PartnerDepot>>(SignalRTags.GetPartnerDepots);
|
||||
public Task<PartnerDepot?> GetPartnerDepotById(int id) => GetByIdAsync<PartnerDepot?>(SignalRTags.GetPartnerDepotById, id);
|
||||
public Task<List<PartnerDepot>?> GetPartnerDepotsByPartnerId(int partnerId) => GetAllAsync<List<PartnerDepot>>(SignalRTags.GetPartnerDepotsByPartnerId, [partnerId]);
|
||||
public Task<PartnerDepot?> AddPartnerDepot(PartnerDepot partnerDepot) => PostDataAsync(SignalRTags.AddPartnerDepot, partnerDepot);
|
||||
public Task<PartnerDepot?> UpdatePartnerDepot(PartnerDepot partnerDepot) => PostDataAsync(SignalRTags.UpdatePartnerDepot, partnerDepot);
|
||||
#endregion PartnerDepot
|
||||
|
||||
#region CargoPartner
|
||||
public Task<List<CargoPartner>?> GetCargoPartners() => GetAllAsync<List<CargoPartner>>(SignalRTags.GetCargoPartners);
|
||||
public Task<CargoPartner?> GetCargoPartnerById(int id) => GetByIdAsync<CargoPartner?>(SignalRTags.GetCargoPartnerById, id);
|
||||
|
|
@ -163,10 +171,10 @@ namespace FruitBankHybrid.Shared.Services.SignalRs
|
|||
=> GetAllAsync<List<ShippingDocument>>(SignalRTags.GetShippingDocumentsByShippingId, [shippingId]);
|
||||
|
||||
public Task<List<ShippingDocument>?> GetShippingDocumentsByProductId(int productId)
|
||||
=> GetAllAsync<List<ShippingDocument>>(SignalRTags.GetShippingDocumentsByShippingId, [productId]);
|
||||
=> GetAllAsync<List<ShippingDocument>>(SignalRTags.GetShippingDocumentsByProductId, [productId]);
|
||||
|
||||
public Task<List<ShippingDocument>?> GetShippingDocumentsByPartnerId(int partnerId)
|
||||
=> GetAllAsync<List<ShippingDocument>>(SignalRTags.GetShippingDocumentsByShippingId, [partnerId]);
|
||||
=> GetAllAsync<List<ShippingDocument>>(SignalRTags.GetShippingDocumentsByPartnerId, [partnerId]);
|
||||
|
||||
public Task<ShippingDocument?> AddShippingDocument(ShippingDocument shippingDocument)
|
||||
=> PostDataAsync(SignalRTags.AddShippingDocument, shippingDocument);
|
||||
|
|
@ -185,18 +193,29 @@ namespace FruitBankHybrid.Shared.Services.SignalRs
|
|||
#endregion Customer
|
||||
|
||||
#region Product
|
||||
//TODO: itt ProductDtoTableItem kéne, csak az AycodeHubProtocol ProductDto-ra deserialize-ol! - J.
|
||||
//public Task<List<ProductDto>?> GetProductDtoTableItems() => GetAllAsync<List<ProductDto>>(SignalRTags.GetProductDtos);
|
||||
// IDEIGLENES gyors fix: a GetProductDtos tagon a szerver List<ProductDto>-t küld, a binár
|
||||
// protokoll viszont a wire-típusba (ProductDto) deszerializál — így a közvetlen
|
||||
// List<ProductDtoTableItem> kérés üres lett (a ProductDtoTableItem a ProductDto kliens-oldali
|
||||
// leszármazottja, amit a szerver nem ismer). A működő GetProductDtos()-t hívjuk, és bináris
|
||||
// round-trippel a kért leszármazottra alakítjuk (azonos mezők). VÉGLEGES megoldás: requestId →
|
||||
// kért-típus a protokollban (AQN-leváltás) — lásd AyCode.Services/docs/SIGNALR_BINARY_PROTOCOL.
|
||||
public async Task<List<ProductDtoTableItem>?> GetProductDtoTableItems()
|
||||
{
|
||||
var dtos = await GetProductDtos();
|
||||
if (dtos == null) return null;
|
||||
|
||||
public Task<List<ProductDtoTableItem>?> GetProductDtoTableItems()
|
||||
=> GetAllAsync<List<ProductDtoTableItem>>(SignalRTags.GetProductDtos);
|
||||
var bytes = SignalRSerializationHelper.SerializeToBinary(dtos);
|
||||
return SignalRSerializationHelper.DeserializeFromBinary<List<ProductDtoTableItem>>(bytes);
|
||||
}
|
||||
|
||||
public Task<List<ProductDto>?> GetProductDtos()
|
||||
=> GetAllAsync<List<ProductDto>>(SignalRTags.GetProductDtos);
|
||||
public Task<List<ProductDto>?> GetProductDtos() => GetAllAsync<List<ProductDto>>(SignalRTags.GetProductDtos);
|
||||
|
||||
//public Task<List<MeasuringProductDto>?> GetAllMeasuringProductDtos()
|
||||
// => GetAllAsync<List<MeasuringProductDto>>(SignalRTags.GetAllMeasuringProductDtos);
|
||||
|
||||
public Task<ProductDto?> GetProductDtoById(int productId)
|
||||
=> GetByIdAsync<ProductDto?>(SignalRTags.GetMeasuringProductDtoById, productId);
|
||||
public Task<ProductDto?> GetProductDtoById(int productId) => GetByIdAsync<ProductDto?>(SignalRTags.GetMeasuringProductDtoById, productId);
|
||||
|
||||
#endregion Product
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue