Compare commits

..

6 Commits

Author SHA1 Message Date
Loretta c9b0bf8334 Enhance ToonDescription docs for PreOrder entities
Expanded and clarified ToonDescription attributes for PreOrder and PreOrderItem classes. Added business rules, constraints, and improved property-level documentation to better describe allocation, conversion, and status logic. No functional changes.
2026-05-30 17:07:29 +02:00
Loretta 98799a79e1 Refactor PreOrder and CargoTruck models, add ICargoTruck
Standardized PreOrder naming across classes, enums, and constants. Updated DB table name constants. Added IsTrailer, Created, and Modified properties to CargoTruck and linked to CargoPartner. Introduced ICargoTruck interface. Added SignalR support for fetching CargoTrucks by CargoPartnerId, with related service, interface, and test updates. Improved ToonDescription docs and updated UI components for new properties and naming. Refactored for clarity and consistency.
2026-05-30 16:26:59 +02:00
Loretta 3e4d3260f0 Add logger support to grids, data sources, and helpers
- Added optional logger to TaskHelper.Forget for fire-and-forget error logging
- Updated MgGridBase and data sources to accept and use logger instances
- Refactored AcSignalRDataSource to log deserialization faults
- Modified constructors and usages of SignalRDataSourceList/Observable for logger injection
- Added CountryCode to CargoTruck and displayed in new GridCargoTruck
- Introduced GridCargoTruck.razor and base class with logger integration
- Updated GridCargoPartner to use new cargo truck grid as detail row
- Improved code style and ensured consistent error handling throughout
2026-05-30 06:47:06 +02:00
Loretta 41ccb10ef7 Add CargoTruck CRUD, grid tabs, and related tests
- Introduced LicencePlate to CargoTruck and Shippings navigation to CargoPartner.
- Implemented CargoTruck CRUD methods in IFruitBankDataControllerCommon and FruitBankSignalRClient.
- Expanded tests for CargoTruck and improved assertions for CargoPartner and Partner.
- Updated CargoPartner grid to show CargoTrucks and Shippings in detail tabs.
- Minor formatting and settings.local.json Bash command update.
2026-05-29 12:16:48 +02:00
Loretta 69010921d7 Add CargoPartner management UI and API integration
- Introduced CRUD operations for CargoPartner in IFruitBankDataControllerCommon and SignalRTags.
- Implemented CargoPartner methods in FruitBankSignalRClient.
- Added GridCargoPartner.razor and GridCargoPartnerBase.cs for CargoPartner grid UI.
- Integrated CargoPartner grid into ShippingsAdmin page.
- Added GetCargoPartnersTest; updated and commented out some tests.
- Added CountryCode column to GridPartner.razor.
- Commented out SandboxEndpointSimpleTests.
- Minor refactoring for new entity and UI support.
2026-05-28 19:48:18 +02:00
Loretta a32f91271d Refactor partner model, add CargoPartner/Truck entities
- Refactored entity classes to be sealed and use new PartnerBase
- Introduced CargoPartner and CargoTruck entities with associations
- Centralized partner properties in abstract PartnerBase
- Updated IPartner, added IPartnerBase and ICargoPartner interfaces
- Added table name constants for new entities in FruitBankConstClient
- Changed AcBinaryHubProtocol FlushPolicy to "Coalesced"
- Cleaned up unused table item classes in DatabaseClient.cs
- Added serialization and documentation attributes to entities
- Updated Preorder and PreorderItem with new structure and docs
2026-05-28 17:47:53 +02:00
44 changed files with 992 additions and 357 deletions

View File

@ -11,7 +11,8 @@
"Bash(while read:*)",
"Bash(do sed -i '1a using AyCode.Core.Serializers.Toons;\\\\n' \"$f\")",
"Bash(done)",
"Bash(rm \"C:/Users/Fullepi/.claude/projects/H--Applications-Mango-Source-FruitBankHybridApp/memory/feedback_framework_docs_no_consumer_types.md\")"
"Bash(rm \"C:/Users/Fullepi/.claude/projects/H--Applications-Mango-Source-FruitBankHybridApp/memory/feedback_framework_docs_no_consumer_types.md\")",
"Bash(cd \"H:/Applications/Aycode/Source/AyCode.Core/AyCode.Services.Server/bin/FruitBank\" && ls -la --time-style=full-iso Debug/net9.0/AyCode.Core.dll Release/net9.0/AyCode.Core.dll 2>&1)"
]
}
}

View File

@ -19,13 +19,13 @@ namespace FruitBank.Common.Server
/// DateTime generic attribute on Product.
/// The start of the window during which this product is visible for preordering.
/// </summary>
public const string PreorderWindowStart = "PreorderWindowStart";
public const string PreOrderWindowStart = "PreOrderWindowStart";
/// <summary>
/// DateTime generic attribute on Product.
/// The end of the window during which this product is visible for preordering.
/// </summary>
public const string PreorderWindowEnd = "PreorderWindowEnd";
public const string PreOrderWindowEnd = "PreOrderWindowEnd";
static FruitBankConst()
{

View File

@ -0,0 +1,21 @@
using AyCode.Core.Serializers.Attributes;
using AyCode.Core.Serializers.Toons;
using FruitBank.Common.Interfaces;
using LinqToDB.Mapping;
using Mango.Nop.Core.Entities;
namespace FruitBank.Common.Entities;
[AcBinarySerializable(false, true, false, true, false, false)]
//[ToonDescription("Business partner with address and tax information", Purpose = "Represents an external legal entity, specifically a Supplier who provides goods or a business partner involved in the procurement chain")]
[Table(Name = FruitBankConstClient.CargoPartnerDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.CargoPartnerDbTableName)]
public sealed class CargoPartner : PartnerBase, ICargoPartner
{
[Association(ThisKey = nameof(Id), OtherKey = nameof(CargoTruck.CargoPartnerId), CanBeNull = true)]
public List<CargoTruck>? CargoTrucks { get; set; }
//[Association(ThisKey = nameof(Id), OtherKey = nameof(Shipping.CargoPartnerId), CanBeNull = true)]
public List<Shipping>? Shippings { get; set; }
//public decimal DecProp{get; set; }
}

View File

@ -0,0 +1,25 @@
using AyCode.Core.Serializers.Attributes;
using FruitBank.Common.Interfaces;
using LinqToDB.Mapping;
using Mango.Nop.Core.Entities;
namespace FruitBank.Common.Entities;
[AcBinarySerializable(false, true, false, true, false, false)]
//[ToonDescription("Business partner with address and tax information", Purpose = "Represents an external legal entity, specifically a Supplier who provides goods or a business partner involved in the procurement chain")]
[Table(Name = FruitBankConstClient.CargoTruckDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.CargoTruckDbTableName)]
public sealed class CargoTruck: MgEntityBase, ICargoTruck
{
public int CargoPartnerId { get; set; }
[Association(ThisKey = nameof(CargoPartnerId), OtherKey = nameof(CargoPartner.Id), CanBeNull = true)]
public CargoPartner CargoPartner { get; set; }
public string CountryCode { get; set; }
public string LicencePlate { get; set; }
public bool IsTrailer { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
}

View File

@ -4,7 +4,7 @@ using Mango.Nop.Core.Entities;
namespace FruitBank.Common.Entities;
public class CustomerCredit: MgEntityBase, IEntityComment
public sealed class CustomerCredit: MgEntityBase, IEntityComment
{
public int CustomerId { get; set; }
public decimal CreditLimit { get; set; }

View File

@ -10,7 +10,7 @@ namespace FruitBank.Common.Entities;
[ToonDescription("Uploaded file with extracted text content", Purpose = "A centralized repository for all uploaded binary content and metadata, featuring a 'RawText' field that stores OCR-extracted information for full-text search and automated data validation across the system")]
[Table(Name = FruitBankConstClient.FilesDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.FilesDbTableName)]
public class Files : MgEntityBase, IFiles
public sealed class Files : MgEntityBase, IFiles
{
public string FileName { get; set; }
public string FileSubPath { get; set; }

View File

@ -16,7 +16,7 @@ namespace FruitBank.Common.Entities;
[ToonDescription("Pallet measurements for order items with audit tracking", Purpose = "A measurement record for outgoing goods, used to verify that the net weight being sent to the customer is accurate and audited. NOTE: Despite the 'Pallet' name, this is a general measurement record that is ALWAYS created for every item. If the product is not measurable (IsMeasurable=false), weights are recorded as 0.0 and only TrayQuantity is stored.")]
[Table(Name = FruitBankConstClient.OrderItemPalletDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.OrderItemPalletDbTableName)]
public class OrderItemPallet : MeasuringItemPalletBase, IOrderItemPallet
public sealed class OrderItemPallet : MeasuringItemPalletBase, IOrderItemPallet
{
public int OrderItemId
{

View File

@ -11,7 +11,7 @@ namespace FruitBank.Common.Entities;
[ToonDescription("Pallet type definition with size and weight")]
[Table(Name = FruitBankConstClient.PalletDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.PalletDbTableName)]
public class Pallet : MgEntityBase, IPallet
public sealed class Pallet : MgEntityBase, IPallet
{
public string Name { get; set; }
public string Size { get; set; }

View File

@ -10,24 +10,8 @@ namespace FruitBank.Common.Entities;
[ToonDescription("Business partner with address and tax information", Purpose = "Represents an external legal entity, specifically a Supplier who provides goods or a business partner involved in the procurement chain")]
[Table(Name = FruitBankConstClient.PartnerDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.PartnerDbTableName)]
public class Partner : MgEntityBase, IPartner
public sealed class Partner : PartnerBase, IPartner
{
public string Name { get; set; }
public string TaxId { get; set; }
public string CertificationNumber { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string State { get; set; }
public string County { get; set; }
public string City { get; set; }
public string Street { get; set; }
[Association(ThisKey = nameof(Id), OtherKey = nameof(ShippingDocument.ShippingId), CanBeNull = true)]
public List<ShippingDocument>? ShippingDocuments { get; set; }
[SkipValuesOnUpdate]
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
}

View File

@ -0,0 +1,25 @@
using FruitBank.Common.Interfaces;
using LinqToDB.Mapping;
using Mango.Nop.Core.Entities;
namespace FruitBank.Common.Entities;
public abstract class PartnerBase : MgEntityBase, IPartnerBase
{
public string Name { get; set; }
public string TaxId { get; set; }
public string CertificationNumber { get; set; }
public string CountryCode { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string State { get; set; }
public string County { get; set; }
public string City { get; set; }
public string Street { get; set; }
[SkipValuesOnUpdate]
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
}

File diff suppressed because one or more lines are too long

View File

@ -1,17 +1,35 @@
using FruitBank.Common.Enums;
using AyCode.Core.Serializers.Attributes;
using AyCode.Core.Serializers.Toons;
using FruitBank.Common.Enums;
using LinqToDB.Mapping;
using Mango.Nop.Core.Entities;
namespace FruitBank.Common.Entities;
[AcBinarySerializable(false, true, false, true, false, false)]
[Table(Name = FruitBankConstClient.PreOrderItemDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.PreOrderItemDbTableName)]
public class PreorderItem : MgEntityBase
[ToonDescription("Single product line of a customer preorder with fulfilment tracking", Purpose = "A requested product line within a PreOrder. Tracks requested versus cumulatively fulfilled quantity as incoming stock is allocated across one or more shipping-document conversion runs.")]
public sealed class PreOrderItem : MgEntityBase
{
public int PreorderId { get; set; }
[ToonDescription(Purpose = "FK to the parent PreOrder.")]
public int PreOrderId { get; set; }
[ToonDescription(Purpose = "FK to the nopCommerce Product being preordered.")]
public int ProductId { get; set; }
[ToonDescription(Purpose = "Quantity of the product the customer requested.", Constraints = "positive")]
public int RequestedQuantity { get; set; }
[ToonDescription(Purpose = "Quantity allocated from incoming stock so far; accumulates across conversion runs until it reaches RequestedQuantity.",
BusinessRule = "this >= 0 && this <= RequestedQuantity")]
public int FulfilledQuantity { get; set; }
[ToonDescription(Purpose = "Gross unit price locked at preorder time. Used as the order-item price on conversion for non-measurable products; measurable products are priced 0 at conversion and weighed afterwards.",
Constraints = "non-negative")]
public decimal UnitPriceInclTax { get; set; }
public PreorderItemStatus Status { get; set; }
[ToonDescription(Purpose = "Item lifecycle: Pending / Fulfilled (fully allocated) / PartiallyFulfilled (partly allocated) / Dropped (expired or no incoming stock).",
BusinessRule = "set during conversion: FulfilledQuantity >= RequestedQuantity ? Fulfilled : FulfilledQuantity > 0 ? PartiallyFulfilled : Dropped; stays Pending until first allocation")]
public PreOrderItemStatus Status { get; set; }
}

View File

@ -11,7 +11,7 @@ namespace FruitBank.Common.Entities;
[ToonDescription("Shipping record with documents and measurement tracking", Purpose = "Represents a physical inbound delivery event (truck arrival) at the warehouse, tracking the vehicle and the overall measurement status of the shipment")]
[Table(Name = FruitBankConstClient.ShippingDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingDbTableName)]
public class Shipping : MgEntityBase, IShipping, IEntityComment
public sealed class Shipping : MgEntityBase, IShipping, IEntityComment
{
public DateTime ShippingDate { get; set; } = DateTime.Now;
public string LicencePlate { get; set; }

View File

@ -11,7 +11,7 @@ namespace FruitBank.Common.Entities;
[ToonDescription("Shipping document with partner, items and files", Purpose = "A digital representation of a supplier's delivery note or invoice associated with the shipment, used for reconciling paper-based data with measured reality")]
[Table(Name = FruitBankConstClient.ShippingDocumentDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingDocumentDbTableName)]
public class ShippingDocument : MgEntityBase, IShippingDocument
public sealed class ShippingDocument : MgEntityBase, IShippingDocument
{
public int PartnerId { get; set; }
public int? ShippingId { get; set; }

View File

@ -12,7 +12,7 @@ namespace FruitBank.Common.Entities;
[ToonDescription("Links shipping documents to files with document type", Purpose = "A many-to-many link table that associates general uploaded files with specific shipping documents, assigning a functional context (DocumentType) to each file, such as identifying which PDF is the supplier's invoice versus the packing list")]
[LinqToDB.Mapping.Table(Name = FruitBankConstClient.ShippingDocumentToFilesDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingDocumentToFilesDbTableName)]
public class ShippingDocumentToFiles : MgEntityBase, IShippingDocumentToFiles
public sealed class ShippingDocumentToFiles : MgEntityBase, IShippingDocumentToFiles
{
public int FilesId { get; set; }

View File

@ -12,7 +12,7 @@ namespace FruitBank.Common.Entities;
[ToonDescription("Pallet measurements for shipping items", Purpose = "The smallest unit of measurement tracking, representing a single physical measurement event. NOTE: Technically named 'Pallet' for legacy reasons, but it is ALWAYS created even if goods arrive without a physical pallet. For non-measurable products, weights are 0.0 and only TrayQuantity is tracked for tare-weight calculations.")]
[LinqToDB.Mapping.Table(Name = FruitBankConstClient.ShippingItemPalletDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingItemPalletDbTableName)]
public class ShippingItemPallet : MeasuringItemPalletBase, IShippingItemPallet
public sealed class ShippingItemPallet : MeasuringItemPalletBase, IShippingItemPallet
{
public int ShippingItemId
{

View File

@ -19,7 +19,7 @@ namespace FruitBank.Common.Entities
[Table(Name = FruitBankConstClient.StockQuantityHistoryExtDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.StockQuantityHistoryExtDbTableName)]
[ToonDescription("Extended weight-metadata for StockQuantityHistory", Purpose = "Validates quantity deltas against measured weight to detect inconsistencies")]
public class StockQuantityHistoryExt : MgEntityBase, IStockQuantityHistoryExt
public sealed class StockQuantityHistoryExt : MgEntityBase, IStockQuantityHistoryExt
{
public int StockQuantityHistoryId { get; set; }

View File

@ -9,7 +9,7 @@ namespace FruitBank.Common.Entities;
[ToonDescription("Inventory session record", Purpose = "Orchestrates inventory sessions by freezing logical stock states")]
[Table(Name = FruitBankConstClient.StockTakingDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.StockTakingDbTableName)]
public class StockTaking : MgStockTaking<StockTakingItem>
public sealed class StockTaking : MgStockTaking<StockTakingItem>
{
public override bool IsReadyForClose()
{

View File

@ -15,7 +15,7 @@ namespace FruitBank.Common.Entities;
[ToonDescription("Line item for product reconciliation", Purpose = "Reconciles snapshot quantity with physical count to calculate final stock delta")]
[Table(Name = FruitBankConstClient.StockTakingItemDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.StockTakingItemDbTableName)]
public class StockTakingItem : MgStockTakingItem<StockTaking, ProductDto>
public sealed class StockTakingItem : MgStockTakingItem<StockTaking, ProductDto>
{
public bool IsMeasurable { get; set; }

View File

@ -18,7 +18,7 @@ public interface IStockTakingItemPallet : IMeasuringItemPalletBase
[ToonDescription("Weight record for inventory item", Purpose = "Granular weight-based evidence for a stock taking line item. NOTE: This record is mandatory for every inventory item. If weighing is skipped (non-measurable), it serves as a container for TrayQuantity with zeroed weight fields. The term 'Pallet' is a legacy naming convention.")]
[LinqToDB.Mapping.Table(Name = FruitBankConstClient.StockTakingItemPalletDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.StockTakingItemPalletDbTableName)]
public class StockTakingItemPallet : MeasuringItemPalletBase, IStockTakingItemPallet
public sealed class StockTakingItemPallet : MeasuringItemPalletBase, IStockTakingItemPallet
{
public int StockTakingItemId
{

View File

@ -1,6 +1,6 @@
namespace FruitBank.Common.Enums;
public enum PreorderItemStatus
public enum PreOrderItemStatus
{
Pending = 0,
Fulfilled = 10,

View File

@ -2,7 +2,7 @@
namespace FruitBank.Common.Enums;
public enum PreorderStatus
public enum PreOrderStatus
{
Pending = 0,
Confirmed = 10,

View File

@ -46,8 +46,11 @@ public static class FruitBankConstClient
public const string StockTakingItemPalletDbTableName = "fbStockTakingItemPallet";
public const string CustomerCreditDbTableName = "fbCustomerCredit";
public const string PreOrderDbTableName = "fbPreorder";
public const string PreOrderItemDbTableName = "fbPreorderItem";
public const string PreOrderDbTableName = "fbPreOrder";
public const string PreOrderItemDbTableName = "fbPreOrderItem";
public const string CargoPartnerDbTableName = "fbCargoPartner";
public const string CargoTruckDbTableName = "fbCargoTruck";
public const string DomainDescription = "This is a nopCommerce plugin developed for FruitBank, a fruit and vegetable wholesaler. The plugin manages supplier inbound delivery (receiving), warehouse weighing (net/gross/pallet/tare weights), and inventory stocktaking. The business logic is centered around FruitBank's requirement for precise physical measurement and quantity tracking.";

View File

@ -0,0 +1,17 @@
using AyCode.Interfaces.Entities;
using AyCode.Interfaces.TimeStampInfo;
using FruitBank.Common.Entities;
namespace FruitBank.Common.Interfaces;
public interface ICargoTruck : IEntityInt, ITimeStampInfo
{
public int CargoPartnerId { get; set; }
public CargoPartner CargoPartner { get; set; }
public string CountryCode { get; set; }
public string LicencePlate { get; set; }
public bool IsTrailer { get; set; }
}

View File

@ -1,6 +1,7 @@
using FruitBank.Common.Dtos;
using FruitBank.Common.Entities;
using FruitBank.Common.Models;
using FruitBank.Common.SignalRs;
using Mango.Nop.Core.Dtos;
using Mango.Nop.Core.Entities;
using Mango.Nop.Core.Models;
@ -19,6 +20,21 @@ public interface IFruitBankDataControllerCommon
public Task<Partner?> UpdatePartner(Partner partner);
#endregion Partner
#region CargoPartner
public Task<List<CargoPartner>?> GetCargoPartners();
public Task<CargoPartner?> GetCargoPartnerById(int id);
public Task<CargoPartner?> AddCargoPartner(CargoPartner cargoPartner);
public Task<CargoPartner?> UpdateCargoPartner(CargoPartner cargoPartner);
#endregion CargoPartner
#region CargoTruck
public Task<List<CargoTruck>?> GetCargoTrucks();
public Task<CargoTruck?> GetCargoTruckById(int id);
public Task<List<CargoTruck>?> GetCargoTrucksByCargoPartnerId(int cargoPartnerId);
public Task<CargoTruck?> AddCargoTruck(CargoTruck cargoTruck);
public Task<CargoTruck?> UpdateCargoTruck(CargoTruck cargoTruck);
#endregion CargoTruck
#region Shipping
public Task<List<Shipping>?> GetShippings();
Task<List<Shipping>?> GetNotMeasuredShippings();

View File

@ -4,17 +4,26 @@ using FruitBank.Common.Entities;
namespace FruitBank.Common.Interfaces;
public interface IPartner : IEntityInt, ITimeStampInfo
public interface ICargoPartner : IPartnerBase
{
List<CargoTruck>? CargoTrucks { get; set; }
}
public interface IPartner : IPartnerBase
{
List<ShippingDocument>? ShippingDocuments { get; set; }
}
public interface IPartnerBase : IEntityInt, ITimeStampInfo
{
string Name { get; set; }
string TaxId { get; set; }
string CertificationNumber { get; set; }
string CountryCode { get; set; }
string PostalCode { get; set; }
string Country { get; set; }
string State { get; set; }
string County { get; set; }
string City { get; set; }
string Street { get; set; }
List<ShippingDocument>? ShippingDocuments { get; set; }
}

View File

@ -15,6 +15,17 @@ public class SignalRTags : AcSignalRTags
public const int AddPartner = 25;
public const int UpdatePartner = 26;
public const int GetCargoPartners = 30;
public const int GetCargoPartnerById = 31;
public const int AddCargoPartner = 32;
public const int UpdateCargoPartner = 33;
public const int GetCargoTrucks = 35;
public const int GetCargoTrucksByCargoPartnerId = 36;
public const int GetCargoTruckById = 37;
public const int AddCargoTruck = 38;
public const int UpdateCargoTruck = 39;
public const int GetShippings = 40;
public const int GetNotMeasuredShippings = 41;
public const int GetShippingById = 42;

View File

@ -42,22 +42,22 @@ namespace FruitBankHybrid.Shared.Tests
var partners = await _signalRClient.GetPartners();
Assert.IsNotNull(partners);
Assert.IsTrue(partners.Count != 0);
Assert.IsNotEmpty(partners);
}
//[DataTestMethod]
//[TestMethod]
//[DataRow(1)]
public async Task<Partner> GetPartnerByIdTest(int partnerId)
{
var partner = await _signalRClient.GetPartnerById(partnerId);
Assert.IsNotNull(partner);
Assert.IsTrue(partner.Id == partnerId);
Assert.AreEqual(partnerId, partner.Id);
return partner;
}
[DataTestMethod]
[TestMethod]
[DataRow(2)]
public async Task UpdatePartnerTest(int partnerId)
{
@ -75,10 +75,108 @@ namespace FruitBankHybrid.Shared.Tests
partner = await _signalRClient.UpdatePartner(partner);
Assert.IsNotNull(partner);
Assert.IsTrue(partner.Id == partnerId);
Assert.AreEqual(partnerId, partner.Id);
}
#endregion Partner
#region CargoPartner
[TestMethod]
public async Task GetCargoPartnersTest()
{
var partners = await _signalRClient.GetCargoPartners();
Assert.IsNotNull(partners);
Assert.IsNotEmpty(partners);
}
//[TestMethod]
//[DataRow(1)]
public async Task<CargoPartner> GetCargoPartnerByIdTest(int cargoPartnerId)
{
var cargoPartner = await _signalRClient.GetCargoPartnerById(cargoPartnerId);
Assert.IsNotNull(cargoPartner);
Assert.AreEqual(cargoPartnerId, cargoPartner.Id);
return cargoPartner;
}
[TestMethod]
[DataRow(1)]
public async Task UpdateCargoPartnerTest(int cargoPartnerId)
{
var cargoPartner = await GetCargoPartnerByIdTest(cargoPartnerId);
var newName = GetFixtureName(cargoPartner.Name);
cargoPartner.Name = newName;
cargoPartner = await _signalRClient.UpdateCargoPartner(cargoPartner);
Assert.IsNotNull(cargoPartner);
Assert.IsTrue(cargoPartner.Name == newName);
cargoPartner.Name = GetOriginalName(cargoPartner.Name);
cargoPartner = await _signalRClient.UpdateCargoPartner(cargoPartner);
Assert.IsNotNull(cargoPartner);
Assert.AreEqual(cargoPartnerId, cargoPartner.Id);
}
#endregion CargoPartner
#region CargoTruck
[TestMethod]
public async Task GetCargoTrucksTest()
{
var cargoTrucks = await _signalRClient.GetCargoTrucks();
Assert.IsNotNull(cargoTrucks);
Assert.IsNotEmpty(cargoTrucks);
}
//[TestMethod]
//[DataRow(1)]
public async Task<CargoTruck> GetCargoTruckByIdTest(int cargoTruckId)
{
var cargoTruck = await _signalRClient.GetCargoTruckById(cargoTruckId);
Assert.IsNotNull(cargoTruck);
Assert.AreEqual(cargoTruckId, cargoTruck.Id);
return cargoTruck;
}
[TestMethod]
[DataRow(1)]
public async Task GetCargoTrucksByCargoPartnerIdTest(int cargoPartnerId)
{
var cargoTrucks = await _signalRClient.GetCargoTrucksByCargoPartnerId(cargoPartnerId);
Assert.IsNotNull(cargoTrucks);
Assert.IsNotEmpty(cargoTrucks);
}
[TestMethod]
[DataRow(1)]
public async Task UpdateCargoTruckTest(int cargoTruckId)
{
var cargoTruck = await GetCargoTruckByIdTest(cargoTruckId);
var newLicencePlate = GetFixtureName(cargoTruck.LicencePlate);
cargoTruck.LicencePlate = newLicencePlate;
cargoTruck = await _signalRClient.UpdateCargoTruck(cargoTruck);
Assert.IsNotNull(cargoTruck);
Assert.IsTrue(cargoTruck.LicencePlate == newLicencePlate);
cargoTruck.LicencePlate = GetOriginalName(cargoTruck.LicencePlate);
cargoTruck = await _signalRClient.UpdateCargoTruck(cargoTruck);
Assert.IsNotNull(cargoTruck);
Assert.AreEqual(cargoTruckId, cargoTruck.Id);
}
#endregion CargoTruck
#region Shipping
[TestMethod]
public async Task GetShippingsTest()
@ -86,7 +184,7 @@ namespace FruitBankHybrid.Shared.Tests
var shippings = await _signalRClient.GetShippings();
Assert.IsNotNull(shippings);
Assert.IsTrue(shippings.Count != 0);
Assert.IsNotEmpty(shippings);
}
[TestMethod]
@ -456,7 +554,7 @@ namespace FruitBankHybrid.Shared.Tests
[DataRow(5, true)]
//[DataRow(6, false)]
[DataRow(33, true)]
[DataRow(64, false)]
//[DataRow(64, false)]
[DataRow(7, true)]
public async Task GetProductDtoByIdTest(int productId, bool isMeasurableExcepted)
{

View File

@ -1,316 +1,316 @@
using AyCode.Core.Enums;
using AyCode.Core.Loggers;
using AyCode.Utils.Extensions;
using FruitBank.Common;
using FruitBank.Common.Dtos;
using FruitBank.Common.Entities;
using FruitBank.Common.Interfaces;
using FruitBank.Common.Loggers;
using FruitBankHybrid.Shared.Services.SignalRs;
using System.Diagnostics.CodeAnalysis;
using FruitBank.Common.SignalRs;
using AyCode.Services.SignalRs;
//using AyCode.Core.Enums;
//using AyCode.Core.Loggers;
//using AyCode.Utils.Extensions;
//using FruitBank.Common;
//using FruitBank.Common.Dtos;
//using FruitBank.Common.Entities;
//using FruitBank.Common.Interfaces;
//using FruitBank.Common.Loggers;
//using FruitBankHybrid.Shared.Services.SignalRs;
//using System.Diagnostics.CodeAnalysis;
//using FruitBank.Common.SignalRs;
//using AyCode.Services.SignalRs;
namespace FruitBankHybrid.Shared.Tests;
//namespace FruitBankHybrid.Shared.Tests;
/// <summary>
/// Teszt a TestSignalREndpoint-hoz.
/// FONTOS: A SANDBOX-ot manu<6E>lisan kell elind<6E>tani a tesztek futtat<61>sa el<65>tt!
/// Ind<6E>t<EFBFBD>s: dotnet run --project Mango.Sandbox.EndPoints --urls http://localhost:59579
/// </summary>
[TestClass]
public class SandboxEndpointSimpleTests
{
private static readonly string SandboxUrl = FruitBankConstClient.BaseUrl; //"http://localhost:59579";
private static readonly string HubUrl = $"{SandboxUrl}/fbHub";
///// <summary>
///// Teszt a TestSignalREndpoint-hoz.
///// FONTOS: A SANDBOX-ot manu<6E>lisan kell elind<6E>tani a tesztek futtat<61>sa el<65>tt!
///// Ind<6E>t<EFBFBD>s: dotnet run --project Mango.Sandbox.EndPoints --urls http://localhost:59579
///// </summary>
//[TestClass]
//public class SandboxEndpointSimpleTests
//{
// private static readonly string SandboxUrl = FruitBankConstClient.BaseUrl; //"http://localhost:59579";
// private static readonly string HubUrl = $"{SandboxUrl}/fbHub";
// Teszt SignalR Tags (TestSignalRTags-b<>l)
private const int PingTag = SignalRTags.PingTag;
private const int EchoTag = SignalRTags.EchoTag;
private const int GetTestItemsTag = 9003;
// // Teszt SignalR Tags (TestSignalRTags-b<>l)
// private const int PingTag = SignalRTags.PingTag;
// private const int EchoTag = SignalRTags.EchoTag;
// private const int GetTestItemsTag = 9003;
private FruitBankSignalRClient _signalRClient = null!;
// private FruitBankSignalRClient _signalRClient = null!;
[TestInitialize]
public void TestInit()
{
if (!SandboxUrl.Contains("localhost:")) throw new Exception("NEM LOCALHOST-ON TESZTEL<45>NK!");
// [TestInitialize]
// public void TestInit()
// {
// if (!SandboxUrl.Contains("localhost:")) throw new Exception("NEM LOCALHOST-ON TESZTEL<45>NK!");
_signalRClient = TestSignalRClientFactory.Create(nameof(SandboxEndpointSimpleTests));
}
// _signalRClient = TestSignalRClientFactory.Create(nameof(SandboxEndpointSimpleTests));
// }
#region HTTP Endpoint Tests
// #region HTTP Endpoint Tests
[TestMethod]
public async Task HealthEndpoint_ReturnsSuccess()
{
using var httpClient = new HttpClient();
var response = await httpClient.GetAsync($"{SandboxUrl}/health");
Assert.IsTrue(response.IsSuccessStatusCode, $"Health endpoint returned {response.StatusCode}");
}
// [TestMethod]
// public async Task HealthEndpoint_ReturnsSuccess()
// {
// using var httpClient = new HttpClient();
// var response = await httpClient.GetAsync($"{SandboxUrl}/health");
// Assert.IsTrue(response.IsSuccessStatusCode, $"Health endpoint returned {response.StatusCode}");
// }
[TestMethod]
public async Task RootEndpoint_ReturnsSandboxIsRunning()
{
using var httpClient = new HttpClient();
var response = await httpClient.GetStringAsync(SandboxUrl);
Assert.AreEqual("SANDBOX is running!", response);
}
// [TestMethod]
// public async Task RootEndpoint_ReturnsSandboxIsRunning()
// {
// using var httpClient = new HttpClient();
// var response = await httpClient.GetStringAsync(SandboxUrl);
// Assert.AreEqual("SANDBOX is running!", response);
// }
#endregion
// #endregion
#region SignalR Connection Tests
// #region SignalR Connection Tests
[TestMethod]
public async Task SignalR_Negotiate_ReturnsSuccess()
{
using var httpClient = new HttpClient();
var response = await httpClient.PostAsync($"{HubUrl}/negotiate?negotiateVersion=1", null);
Assert.IsTrue(response.IsSuccessStatusCode, $"SignalR negotiate returned {response.StatusCode}");
}
// [TestMethod]
// public async Task SignalR_Negotiate_ReturnsSuccess()
// {
// using var httpClient = new HttpClient();
// var response = await httpClient.PostAsync($"{HubUrl}/negotiate?negotiateVersion=1", null);
// Assert.IsTrue(response.IsSuccessStatusCode, $"SignalR negotiate returned {response.StatusCode}");
// }
[TestMethod]
public async Task SignalR_Connect_Succeeds()
{
var testItems = await _signalRClient.GetAllAsync<List<TestItem>>(GetTestItemsTag);
Assert.IsNotNull(testItems);
}
// [TestMethod]
// public async Task SignalR_Connect_Succeeds()
// {
// var testItems = await _signalRClient.GetAllAsync<List<TestItem>>(GetTestItemsTag);
// Assert.IsNotNull(testItems);
// }
public class TestItem
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public decimal Value { get; set; }
}
// public class TestItem
// {
// public int Id { get; set; }
// public string Name { get; set; } = string.Empty;
// public decimal Value { get; set; }
// }
//[TestMethod]
//public async Task SignalR_Connect_Succeeds()
//{
// var connection = new HubConnectionBuilder()
// .WithUrl(HubUrl)
// .Build();
////[TestMethod]
// //public async Task SignalR_Connect_Succeeds()
// //{
// // var connection = new HubConnectionBuilder()
// // .WithUrl(HubUrl)
// // .Build();
// try
// {
// await connection.StartAsync();
// Assert.AreEqual(HubConnectionState.Connected, connection.State);
// }
// finally
// {
// await connection.StopAsync();
// }
//}
// // try
// // {
// // await connection.StartAsync();
// // Assert.AreEqual(HubConnectionState.Connected, connection.State);
// // }
// // finally
// // {
// // await connection.StopAsync();
// // }
// //}
//#endregion
// //#endregion
//#region TestSignalREndpoint Tests
// //#region TestSignalREndpoint Tests
//[TestMethod]
//public async Task SignalR_Ping_ReturnsResponse()
//{
// var testMessage = "Hello SignalR!";
// await TestSignalREndpoint(PingTag, testMessage, "Ping", response =>
// {
// Assert.IsNotNull(response, "Response should not be null");
// //[TestMethod]
// //public async Task SignalR_Ping_ReturnsResponse()
// //{
// // var testMessage = "Hello SignalR!";
// // await TestSignalREndpoint(PingTag, testMessage, "Ping", response =>
// // {
// // Assert.IsNotNull(response, "Response should not be null");
// // Parse JSON response
// using var jsonDoc = JsonDocument.Parse(response);
// var root = jsonDoc.RootElement;
// // // Parse JSON response
// // using var jsonDoc = JsonDocument.Parse(response);
// // var root = jsonDoc.RootElement;
// // Ellen<65>rizz<7A>k, hogy van Message property
// Assert.IsTrue(root.TryGetProperty("Message", out var messageElement) ||
// root.TryGetProperty("message", out messageElement),
// "Response should contain 'Message' property");
// // // Ellen<65>rizz<7A>k, hogy van Message property
// // Assert.IsTrue(root.TryGetProperty("Message", out var messageElement) ||
// // root.TryGetProperty("message", out messageElement),
// // "Response should contain 'Message' property");
// Console.WriteLine($"[Ping] Received message: {messageElement.GetString()}");
// });
//}
// // Console.WriteLine($"[Ping] Received message: {messageElement.GetString()}");
// // });
// //}
//[TestMethod]
//public async Task SignalR_Echo_ReturnsEchoedData()
//{
// var request = new { Id = 42, Name = "TestName" };
// await TestSignalREndpoint(EchoTag, request, "Echo", response =>
// {
// Assert.IsNotNull(response, "Response should not be null");
// //[TestMethod]
// //public async Task SignalR_Echo_ReturnsEchoedData()
// //{
// // var request = new { Id = 42, Name = "TestName" };
// // await TestSignalREndpoint(EchoTag, request, "Echo", response =>
// // {
// // Assert.IsNotNull(response, "Response should not be null");
// using var jsonDoc = JsonDocument.Parse(response);
// var root = jsonDoc.RootElement;
// // using var jsonDoc = JsonDocument.Parse(response);
// // var root = jsonDoc.RootElement;
// // Ellen<65>rizz<7A>k az Id-t
// Assert.IsTrue(root.TryGetProperty("Id", out var idElement) ||
// root.TryGetProperty("id", out idElement),
// "Response should contain 'Id' property");
// Assert.AreEqual(42, idElement.GetInt32(), "Id should be 42");
// // // Ellen<65>rizz<7A>k az Id-t
// // Assert.IsTrue(root.TryGetProperty("Id", out var idElement) ||
// // root.TryGetProperty("id", out idElement),
// // "Response should contain 'Id' property");
// // Assert.AreEqual(42, idElement.GetInt32(), "Id should be 42");
// // Ellen<65>rizz<7A>k a Name-et
// Assert.IsTrue(root.TryGetProperty("Name", out var nameElement) ||
// root.TryGetProperty("name", out nameElement),
// "Response should contain 'Name' property");
// Assert.AreEqual("TestName", nameElement.GetString(), "Name should be 'TestName'");
// // // Ellen<65>rizz<7A>k a Name-et
// // Assert.IsTrue(root.TryGetProperty("Name", out var nameElement) ||
// // root.TryGetProperty("name", out nameElement),
// // "Response should contain 'Name' property");
// // Assert.AreEqual("TestName", nameElement.GetString(), "Name should be 'TestName'");
// Console.WriteLine($"[Echo] Received: Id={idElement.GetInt32()}, Name={nameElement.GetString()}");
// });
//}
// // Console.WriteLine($"[Echo] Received: Id={idElement.GetInt32()}, Name={nameElement.GetString()}");
// // });
// //}
//[TestMethod]
//public async Task SignalR_GetTestItems_ReturnsItemList()
//{
// await TestSignalREndpoint(GetTestItemsTag, null, "GetTestItems", response =>
// {
// Assert.IsNotNull(response, "Response should not be null");
// //[TestMethod]
// //public async Task SignalR_GetTestItems_ReturnsItemList()
// //{
// // await TestSignalREndpoint(GetTestItemsTag, null, "GetTestItems", response =>
// // {
// // Assert.IsNotNull(response, "Response should not be null");
// using var jsonDoc = JsonDocument.Parse(response);
// var root = jsonDoc.RootElement;
// // using var jsonDoc = JsonDocument.Parse(response);
// // var root = jsonDoc.RootElement;
// // Ellen<65>rizz<7A>k, hogy t<>mb-e
// Assert.AreEqual(JsonValueKind.Array, root.ValueKind, "Response should be an array");
// Assert.IsTrue(root.GetArrayLength() > 0, "Array should have items");
// // // Ellen<65>rizz<7A>k, hogy t<>mb-e
// // Assert.AreEqual(JsonValueKind.Array, root.ValueKind, "Response should be an array");
// // Assert.IsTrue(root.GetArrayLength() > 0, "Array should have items");
// Console.WriteLine($"[GetTestItems] Received {root.GetArrayLength()} items");
// // Console.WriteLine($"[GetTestItems] Received {root.GetArrayLength()} items");
// // Ellen<65>rizz<7A>k az els<6C> elemet
// var firstItem = root[0];
// Assert.IsTrue(firstItem.TryGetProperty("Id", out _) || firstItem.TryGetProperty("id", out _),
// "Item should have 'Id' property");
// Assert.IsTrue(firstItem.TryGetProperty("Name", out _) || firstItem.TryGetProperty("name", out _),
// "Item should have 'Name' property");
// });
//}
// // // Ellen<65>rizz<7A>k az els<6C> elemet
// // var firstItem = root[0];
// // Assert.IsTrue(firstItem.TryGetProperty("Id", out _) || firstItem.TryGetProperty("id", out _),
// // "Item should have 'Id' property");
// // Assert.IsTrue(firstItem.TryGetProperty("Name", out _) || firstItem.TryGetProperty("name", out _),
// // "Item should have 'Name' property");
// // });
// //}
//#endregion
// //#endregion
//#region EREDETI BUSINESS ENDPOINT TESZTEK - KIKOMMENTEZVE
// //#region EREDETI BUSINESS ENDPOINT TESZTEK - KIKOMMENTEZVE
//// ===========================================
//// === Az al<61>bbi tesztek az eredeti 3 endpoint-ot tesztelik ===
//// === Vissza<7A>ll<6C>t<EFBFBD>shoz: t<>r<EFBFBD>ld a kommenteket <20>s regisztr<74>ld az endpoint-okat a Program.cs-ben ===
//// ===========================================
// //// ===========================================
// //// === Az al<61>bbi tesztek az eredeti 3 endpoint-ot tesztelik ===
// //// === Vissza<7A>ll<6C>t<EFBFBD>shoz: t<>r<EFBFBD>ld a kommenteket <20>s regisztr<74>ld az endpoint-okat a Program.cs-ben ===
// //// ===========================================
//// [TestMethod]
//// public async Task SignalR_GetMeasuringUsers_ReturnsJson()
//// {
//// await TestSignalREndpoint(GetMeasuringUsersTag, null, "GetMeasuringUsers");
//// }
// //// [TestMethod]
// //// public async Task SignalR_GetMeasuringUsers_ReturnsJson()
// //// {
// //// await TestSignalREndpoint(GetMeasuringUsersTag, null, "GetMeasuringUsers");
// //// }
//// [TestMethod]
//// public async Task SignalR_GetStockQuantityHistoryDtos_ReturnsJson()
//// {
//// await TestSignalREndpoint(GetStockQuantityHistoryDtosTag, null, "GetStockQuantityHistoryDtos");
//// }
// //// [TestMethod]
// //// public async Task SignalR_GetStockQuantityHistoryDtos_ReturnsJson()
// //// {
// //// await TestSignalREndpoint(GetStockQuantityHistoryDtosTag, null, "GetStockQuantityHistoryDtos");
// //// }
//// [TestMethod]
//// public async Task SignalR_GetStockQuantityHistoryDtosByProductId_ReturnsJson()
//// {
//// // ProductId = 10
//// await TestSignalREndpoint(GetStockQuantityHistoryDtosByProductIdTag, 10, "GetStockQuantityHistoryDtosByProductId");
//// }
// //// [TestMethod]
// //// public async Task SignalR_GetStockQuantityHistoryDtosByProductId_ReturnsJson()
// //// {
// //// // ProductId = 10
// //// await TestSignalREndpoint(GetStockQuantityHistoryDtosByProductIdTag, 10, "GetStockQuantityHistoryDtosByProductId");
// //// }
//// [TestMethod]
//// public async Task SignalR_GetShippingDocumentsByShippingId_ReturnsJson()
//// {
//// // ShippingId = 5
//// await TestSignalREndpoint(GetShippingDocumentsByShippingIdTag, 5, "GetShippingDocumentsByShippingId");
//// }
// //// [TestMethod]
// //// public async Task SignalR_GetShippingDocumentsByShippingId_ReturnsJson()
// //// {
// //// // ShippingId = 5
// //// await TestSignalREndpoint(GetShippingDocumentsByShippingIdTag, 5, "GetShippingDocumentsByShippingId");
// //// }
//// [TestMethod]
//// public async Task SignalR_GetOrderDtoById_ReturnsJson()
//// {
//// // OrderId = 15
//// await TestSignalREndpoint(GetOrderDtoByIdTag, 15, "GetOrderDtoById");
//// }
// //// [TestMethod]
// //// public async Task SignalR_GetOrderDtoById_ReturnsJson()
// //// {
// //// // OrderId = 15
// //// await TestSignalREndpoint(GetOrderDtoByIdTag, 15, "GetOrderDtoById");
// //// }
//// [TestMethod]
//// public async Task SignalR_GetStockTakingItemsById_ReturnsJson()
//// {
//// // StockTakingItemId = 200
//// await TestSignalREndpoint(GetStockTakingItemsByIdTag, 200, "GetStockTakingItemsById");
//// }
// //// [TestMethod]
// //// public async Task SignalR_GetStockTakingItemsById_ReturnsJson()
// //// {
// //// // StockTakingItemId = 200
// //// await TestSignalREndpoint(GetStockTakingItemsByIdTag, 200, "GetStockTakingItemsById");
// //// }
//#endregion
// //#endregion
//#region Helper Methods
// //#region Helper Methods
//private async Task TestSignalREndpoint(int tag, object? parameter, string endpointName, Action<string?>? validateResponse = null)
//{
// var connection = new HubConnectionBuilder()
// .WithUrl(HubUrl)
// .Build();
// //private async Task TestSignalREndpoint(int tag, object? parameter, string endpointName, Action<string?>? validateResponse = null)
// //{
// // var connection = new HubConnectionBuilder()
// // .WithUrl(HubUrl)
// // .Build();
// string? receivedJson = null;
// int receivedTag = -1;
// var responseReceived = new TaskCompletionSource<bool>();
// // string? receivedJson = null;
// // int receivedTag = -1;
// // var responseReceived = new TaskCompletionSource<bool>();
// connection.On<int, byte[]>("ReceiveMessage", (responseTag, data) =>
// {
// receivedTag = responseTag;
// if (data != null && data.Length > 0)
// {
// receivedJson = Encoding.UTF8.GetString(data);
// }
// responseReceived.TrySetResult(true);
// });
// // connection.On<int, byte[]>("ReceiveMessage", (responseTag, data) =>
// // {
// // receivedTag = responseTag;
// // if (data != null && data.Length > 0)
// // {
// // receivedJson = Encoding.UTF8.GetString(data);
// // }
// // responseReceived.TrySetResult(true);
// // });
// try
// {
// await connection.StartAsync();
// Assert.AreEqual(HubConnectionState.Connected, connection.State, $"Failed to connect to SignalR hub for {endpointName}");
// // try
// // {
// // await connection.StartAsync();
// // Assert.AreEqual(HubConnectionState.Connected, connection.State, $"Failed to connect to SignalR hub for {endpointName}");
// // K<>sz<73>ts<74>k el a request data-t
// // Ha nincs param<61>ter, null-t k<>ld<6C>nk (nem <20>res byte t<>mb<6D>t!)
// byte[]? requestData = parameter != null
// ? Encoding.UTF8.GetBytes(JsonSerializer.Serialize(parameter))
// : null;
// // // K<>sz<73>ts<74>k el a request data-t
// // // Ha nincs param<61>ter, null-t k<>ld<6C>nk (nem <20>res byte t<>mb<6D>t!)
// // byte[]? requestData = parameter != null
// // ? Encoding.UTF8.GetBytes(JsonSerializer.Serialize(parameter))
// // : null;
// // A Hub met<65>dus neve: OnReceiveMessage (3 param<61>ter: messageTag, messageBytes, requestId)
// await connection.InvokeAsync("OnReceiveMessage", tag, requestData, (int?)null);
// // // A Hub met<65>dus neve: OnReceiveMessage (3 param<61>ter: messageTag, messageBytes, requestId)
// // await connection.InvokeAsync("OnReceiveMessage", tag, requestData, (int?)null);
// var completed = await Task.WhenAny(responseReceived.Task, Task.Delay(15000));
// // var completed = await Task.WhenAny(responseReceived.Task, Task.Delay(15000));
// if (completed == responseReceived.Task)
// {
// Console.WriteLine($"[{endpointName}] Response tag: {receivedTag}");
// Console.WriteLine($"[{endpointName}] Response JSON: {receivedJson?.Substring(0, Math.Min(500, receivedJson?.Length ?? 0))}...");
// // if (completed == responseReceived.Task)
// // {
// // Console.WriteLine($"[{endpointName}] Response tag: {receivedTag}");
// // Console.WriteLine($"[{endpointName}] Response JSON: {receivedJson?.Substring(0, Math.Min(500, receivedJson?.Length ?? 0))}...");
// // Ellen<65>rizz<7A>k, hogy valid JSON-e (ha van adat)
// if (!string.IsNullOrEmpty(receivedJson))
// {
// try
// {
// using var jsonDoc = JsonDocument.Parse(receivedJson);
// Assert.IsTrue(
// jsonDoc.RootElement.ValueKind == JsonValueKind.Array ||
// jsonDoc.RootElement.ValueKind == JsonValueKind.Object ||
// jsonDoc.RootElement.ValueKind == JsonValueKind.Null,
// $"[{endpointName}] Response is not a valid JSON");
// // // Ellen<65>rizz<7A>k, hogy valid JSON-e (ha van adat)
// // if (!string.IsNullOrEmpty(receivedJson))
// // {
// // try
// // {
// // using var jsonDoc = JsonDocument.Parse(receivedJson);
// // Assert.IsTrue(
// // jsonDoc.RootElement.ValueKind == JsonValueKind.Array ||
// // jsonDoc.RootElement.ValueKind == JsonValueKind.Object ||
// // jsonDoc.RootElement.ValueKind == JsonValueKind.Null,
// // $"[{endpointName}] Response is not a valid JSON");
// // Custom validation
// validateResponse?.Invoke(receivedJson);
// }
// catch (JsonException ex)
// {
// Assert.Fail($"[{endpointName}] Invalid JSON response: {ex.Message}");
// }
// }
// }
// else
// {
// Assert.AreEqual(HubConnectionState.Connected, connection.State,
// $"[{endpointName}] Connection was closed - check SANDBOX logs for DI errors");
// }
// }
// catch (Exception ex)
// {
// Assert.Fail($"[{endpointName}] SignalR error: {ex.Message}. Check SANDBOX logs for missing DI registrations.");
// }
// finally
// {
// if (connection.State == HubConnectionState.Connected)
// {
// await connection.StopAsync();
// }
// }
//}
// // // Custom validation
// // validateResponse?.Invoke(receivedJson);
// // }
// // catch (JsonException ex)
// // {
// // Assert.Fail($"[{endpointName}] Invalid JSON response: {ex.Message}");
// // }
// // }
// // }
// // else
// // {
// // Assert.AreEqual(HubConnectionState.Connected, connection.State,
// // $"[{endpointName}] Connection was closed - check SANDBOX logs for DI errors");
// // }
// // }
// // catch (Exception ex)
// // {
// // Assert.Fail($"[{endpointName}] SignalR error: {ex.Message}. Check SANDBOX logs for missing DI registrations.");
// // }
// // finally
// // {
// // if (connection.State == HubConnectionState.Connected)
// // {
// // await connection.StopAsync();
// // }
// // }
// //}
#endregion
}
// #endregion
//}

View File

@ -86,6 +86,7 @@ public class FullProcessModel
{
public List<Shipping> Shippings { get; set; }
public List<OrderDto> Orders { get; set; }
public List<PreOrder> PreOrders { get; set; }
public List<StockTaking> StockTakings { get; set; }
}

View File

@ -276,15 +276,13 @@
private async Task Callback(ToolbarItemClickEventArgs obj)
{
if (windowVisible)
await windowRef.CloseAsync();
else
await windowRef.ShowAsync();
if (windowVisible) await windowRef.CloseAsync();
else await windowRef.ShowAsync();
}
private void Callback2(WindowClosingEventArgs obj)
{
ReloadDataFromDb(true).Forget();
ReloadDataFromDb(true).Forget(_logger);
}
}

View File

@ -0,0 +1,125 @@
@using System.Collections.ObjectModel
@using AyCode.Blazor.Components.Components.Grids
@using AyCode.Core.Helpers
@using AyCode.Core.Loggers
@using AyCode.Utils.Extensions
@using FruitBank.Common.Dtos
@using FruitBank.Common.Entities
@using FruitBankHybrid.Shared.Components.Grids.Shippings
@using FruitBankHybrid.Shared.Databases
@using FruitBankHybrid.Shared.Services.Loggers
@using FruitBankHybrid.Shared.Services.SignalRs
@inject IEnumerable<IAcLogWriterClientBase> LogWriters
@inject FruitBankSignalRClient FruitBankSignalRClient
<MgGridWithInfoPanel ShowInfoPanel="@IsMasterGrid">
<GridContent>
<GridCargoPartnerBase @ref="Grid"
DataSource="CargoPartners"
AutoSaveLayoutName="GridCargoPartner"
SignalRClient="FruitBankSignalRClient"
Logger="_logger"
CssClass="@GridCss"
ValidationEnabled="false"
OnGridFocusedRowChanged="Grid_FocusedRowChanged">
<Columns>
<DxGridDataColumn FieldName="Id" SortIndex="0" SortOrder="GridColumnSortOrder.Descending" ReadOnly="true" />
<DxGridDataColumn FieldName="Name" />
<DxGridDataColumn FieldName="TaxId" />
<DxGridDataColumn FieldName="CertificationNumber" />
<DxGridDataColumn FieldName="@nameof(CargoPartner.CountryCode)" />
<DxGridDataColumn FieldName="PostalCode" />
<DxGridDataColumn FieldName="@nameof(CargoPartner.Country)" />
<DxGridDataColumn FieldName="State" />
<DxGridDataColumn FieldName="County" />
<DxGridDataColumn FieldName="City" />
<DxGridDataColumn FieldName="Street" />
<DxGridDataColumn FieldName="Created" ReadOnly="true" />
<DxGridDataColumn FieldName="Modified" ReadOnly="true" />
<DxGridCommandColumn Visible="!IsMasterGrid" Width="120"></DxGridCommandColumn>
</Columns>
<DetailRowTemplate>
@if (IsMasterGrid)
{
var cargoPartner = ((CargoPartner)context.DataItem);
var shippings = cargoPartner?.Shippings ?? [];
var cargoTrucks = cargoPartner?.CargoTrucks ?? [];
<DxTabs>
<DxTabPage Text="Kamionok">
@{
var observableCargoTruck = new AcObservableCollection<CargoTruck>(cargoTrucks);
<GridCargoTruck ParentDataItem="@cargoPartner" CargoTrucks="@observableCargoTruck"></GridCargoTruck>
}
</DxTabPage>
<DxTabPage Text="Szállítmányok">
@{
var observableShippings = new AcObservableCollection<Shipping>(shippings);
<GridShipping Shippings="@observableShippings" IsMasterGrid="false" />
}
</DxTabPage>
</DxTabs>
}
</DetailRowTemplate>
<ToolbarTemplate>
@if (IsMasterGrid)
{
<MgGridToolbarTemplate Grid="Grid" OnReloadDataClick="() => ReloadDataFromDb(true)" />
}
</ToolbarTemplate>
</GridCargoPartnerBase>
</GridContent>
</MgGridWithInfoPanel>
@code {
//[Inject] public required ObjectLock ObjectLock { get; set; }
[Inject] public required DatabaseClient Database { get; set; }
[Parameter] public bool IsMasterGrid { get; set; } = false;
[Parameter] public AcObservableCollection<CargoPartner>? CargoPartners { get; set; }
[Parameter] public AcObservableCollection<Shipping>? Shippings { get; set; }
const string ExportFileName = "ExportResult";
string GridSearchText = "";
bool EditItemsEnabled { get; set; }
int FocusedRowVisibleIndex { get; set; }
public GridCargoPartnerBase Grid { get; set; }
string GridCss => !IsMasterGrid ? "hide-toolbar" : string.Empty;
private int _activeTabIndex;
private LoggerClient<GridCargoPartner> _logger;
protected override async Task OnInitializedAsync()
{
_logger = new LoggerClient<GridCargoPartner>(LogWriters.ToArray());
await ReloadDataFromDb(false);
}
private async Task ReloadDataFromDb(bool forceReload = false)
{
if (!IsMasterGrid) return;
if (Grid == null) return;
using (await ObjectLock.GetSemaphore<CargoPartner>().UseWaitAsync())
if (forceReload) await Grid.ReloadDataSourceAsync();
if (forceReload) Grid.Reload();
}
async Task Grid_FocusedRowChanged(GridFocusedRowChangedEventArgs args)
{
if (Grid == null) return;
if (Grid.IsEditing() && !Grid.IsEditingNewRow())
await Grid.SaveChangesAsync();
FocusedRowVisibleIndex = args.VisibleIndex;
EditItemsEnabled = true;
}
}

View File

@ -0,0 +1,67 @@
using AyCode.Core.Interfaces;
using DevExpress.Blazor;
using FruitBank.Common.Entities;
using FruitBank.Common.Interfaces;
using FruitBank.Common.SignalRs;
using FruitBankHybrid.Shared.Pages;
using Microsoft.AspNetCore.Components;
namespace FruitBankHybrid.Shared.Components.Grids.Cargos;
public class GridCargoPartnerBase: FruitBankGridBase<CargoPartner>, IGrid
{
private bool _isFirstInitializeParameterCore;
private bool _isFirstInitializeParameters;
public GridCargoPartnerBase() : base()
{
GetAllMessageTag = SignalRTags.GetCargoPartners;
AddMessageTag = SignalRTags.AddCargoPartner;
UpdateMessageTag = SignalRTags.UpdateCargoPartner;
//RemoveMessageTag = SignalRTags.;
}
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
}
protected override void OnParametersSet()
{
base.OnParametersSet();
if (!_isFirstInitializeParameters)
{
//if (!IsMasterGrid && (ContextIds == null || ContextIds.Length == 0))
//{
// ContextIds = [ParentDataItem!.Id];
// GetAllMessageTag = SignalRTags.GetShippingItemsByDocumentId;
//}
_isFirstInitializeParameters = false;
}
}
protected override async Task SetParametersAsyncCore(ParameterView parameters)
{
await base.SetParametersAsyncCore(parameters);
if (!_isFirstInitializeParameterCore)
{
//if (!IsMasterGrid && (ContextIds == null || ContextIds.Length == 0))
//{
// ContextIds = [ParentDataItem!.Id];
// GetAllMessageTag = SignalRTags.GetShippingItemsByDocumentId;
//}
//ShowFilterRow = true;
//ShowGroupPanel = true;
//AllowSort = false;
//etc...
_isFirstInitializeParameterCore = false;
}
}
}

View File

@ -0,0 +1,100 @@
@using System.Collections.ObjectModel
@using AyCode.Blazor.Components.Components.Grids
@using AyCode.Core.Helpers
@using AyCode.Core.Interfaces
@using AyCode.Core.Loggers
@using AyCode.Utils.Extensions
@using FruitBank.Common.Dtos
@using FruitBank.Common.Entities
@using FruitBankHybrid.Shared.Components.Grids.Shippings
@using FruitBankHybrid.Shared.Databases
@using FruitBankHybrid.Shared.Services.Loggers
@using FruitBankHybrid.Shared.Services.SignalRs
@inject IEnumerable<IAcLogWriterClientBase> LogWriters
@inject FruitBankSignalRClient FruitBankSignalRClient
<MgGridWithInfoPanel ShowInfoPanel="@IsMasterGrid">
<GridContent>
<GridCargoTruckBase @ref="Grid"
DataSource="CargoTrucks"
ParentDataItem="ParentDataItem"
AutoSaveLayoutName="GridCargoTruck"
SignalRClient="FruitBankSignalRClient"
Logger="_logger"
CssClass="@GridCss"
ValidationEnabled="false"
OnGridFocusedRowChanged="Grid_FocusedRowChanged">
<Columns>
<DxGridDataColumn FieldName="Id" SortIndex="0" SortOrder="GridColumnSortOrder.Descending" ReadOnly="true" />
<DxGridDataColumn FieldName="@nameof(CargoTruck.LicencePlate)" />
<DxGridDataColumn FieldName="@nameof(CargoTruck.CountryCode)" />
<DxGridDataColumn FieldName="@nameof(CargoTruck.IsTrailer)" />
<DxGridDataColumn FieldName="Created" ReadOnly="true" />
<DxGridDataColumn FieldName="Modified" ReadOnly="true" />
<DxGridCommandColumn Visible="!IsMasterGrid" Width="120"></DxGridCommandColumn>
</Columns>
<ToolbarTemplate>
@if (IsMasterGrid)
{
<MgGridToolbarTemplate Grid="Grid" OnReloadDataClick="() => ReloadDataFromDb(true)" />
}
</ToolbarTemplate>
</GridCargoTruckBase>
</GridContent>
</MgGridWithInfoPanel>
@code {
//[Inject] public required ObjectLock ObjectLock { get; set; }
[Inject] public required DatabaseClient Database { get; set; }
[Parameter] public AcObservableCollection<CargoTruck>? CargoTrucks { get; set; }
const string ExportFileName = "ExportResult";
string GridSearchText = "";
bool EditItemsEnabled { get; set; }
int FocusedRowVisibleIndex { get; set; }
public GridCargoTruckBase Grid { get; set; }
string GridCss => !IsMasterGrid ? "hide-toolbar" : string.Empty;
[Parameter] public IId<int>? ParentDataItem { get; set; }
public bool IsMasterGrid => ParentDataItem == null;
public bool ParentDataItemIsCargoPartner => (ParentDataItem is CargoPartner);
private int _activeTabIndex;
private LoggerClient<GridCargoTruck> _logger;
protected override async Task OnInitializedAsync()
{
_logger = new LoggerClient<GridCargoTruck>(LogWriters.ToArray());
await ReloadDataFromDb(false);
}
private async Task ReloadDataFromDb(bool forceReload = false)
{
if (!IsMasterGrid) return;
if (Grid == null) return;
using (await ObjectLock.GetSemaphore<CargoTruck>().UseWaitAsync())
if (forceReload) await Grid.ReloadDataSourceAsync();
if (forceReload) Grid.Reload();
}
async Task Grid_FocusedRowChanged(GridFocusedRowChangedEventArgs args)
{
if (Grid == null) return;
if (Grid.IsEditing() && !Grid.IsEditingNewRow())
await Grid.SaveChangesAsync();
FocusedRowVisibleIndex = args.VisibleIndex;
EditItemsEnabled = true;
}
}

View File

@ -0,0 +1,85 @@
using AyCode.Core.Interfaces;
using AyCode.Utils.Extensions;
using DevExpress.Blazor;
using FruitBank.Common.Entities;
using FruitBank.Common.Interfaces;
using FruitBank.Common.SignalRs;
using FruitBankHybrid.Shared.Pages;
using Microsoft.AspNetCore.Components;
namespace FruitBankHybrid.Shared.Components.Grids.Cargos;
public class GridCargoTruckBase: FruitBankGridBase<CargoTruck>, IGrid
{
private bool _isFirstInitializeParameterCore;
private bool _isFirstInitializeParameters;
public GridCargoTruckBase() : base()
{
//GetAllMessageTag = SignalRTags.GetCargoTrucks;
AddMessageTag = SignalRTags.AddCargoTruck;
UpdateMessageTag = SignalRTags.UpdateCargoTruck;
//RemoveMessageTag = SignalRTags.;
}
protected override async Task OnInitializedAsync()
{
if (GetAllMessageTag > 0) return;
if (IsMasterGrid) GetAllMessageTag = SignalRTags.GetCargoTrucks;
else
{
if (ContextIds == null || ContextIds.Length == 0) ContextIds = [ParentDataItem!.Id];
switch (ParentDataItem)
{
case ICargoPartner:
GetAllMessageTag = SignalRTags.GetCargoTrucksByCargoPartnerId;
if (KeyFieldNameToParentId.IsNullOrWhiteSpace()) KeyFieldNameToParentId = nameof(CargoTruck.CargoPartnerId);
break;
}
}
await base.OnInitializedAsync();
}
protected override void OnParametersSet()
{
base.OnParametersSet();
if (!_isFirstInitializeParameters)
{
//if (!IsMasterGrid && (ContextIds == null || ContextIds.Length == 0))
//{
// ContextIds = [ParentDataItem!.Id];
// GetAllMessageTag = SignalRTags.GetShippingItemsByDocumentId;
//}
_isFirstInitializeParameters = false;
}
}
protected override async Task SetParametersAsyncCore(ParameterView parameters)
{
await base.SetParametersAsyncCore(parameters);
if (!_isFirstInitializeParameterCore)
{
//if (!IsMasterGrid && (ContextIds == null || ContextIds.Length == 0))
//{
// ContextIds = [ParentDataItem!.Id];
// GetAllMessageTag = SignalRTags.GetShippingItemsByDocumentId;
//}
//ShowFilterRow = true;
//ShowGroupPanel = true;
//AllowSort = false;
//etc...
_isFirstInitializeParameterCore = false;
}
}
}

View File

@ -29,6 +29,7 @@
<DxGridDataColumn FieldName="Name" />
<DxGridDataColumn FieldName="TaxId" />
<DxGridDataColumn FieldName="CertificationNumber" />
<DxGridDataColumn FieldName="@nameof(Partner.CountryCode)" />
<DxGridDataColumn FieldName="PostalCode" />
<DxGridDataColumn FieldName="@nameof(Partner.Country)" />
<DxGridDataColumn FieldName="State" />

View File

@ -1,5 +1,7 @@
using AyCode.Core.Extensions;
using AyCode.Core.Helpers;
using AyCode.Core.Interfaces;
using AyCode.Core.Loggers;
using AyCode.Interfaces.Entities;
using AyCode.Services.SignalRs;
using AyCode.Utils.Extensions;
@ -15,18 +17,14 @@ using Nop.Core.Domain.Orders;
using System.Collections.Concurrent;
using System.Collections.ObjectModel;
using System.Threading;
using AyCode.Core.Helpers;
namespace FruitBankHybrid.Shared.Databases;
public class ShippingTableItem : Shipping
{ }
public class ShippingDocumentTableItem : ShippingDocument
{ }
//public class ShippingTableItem : Shipping { }
//public class ShippingDocumentTableItem : ShippingDocument { }
public class ShippingItemTableItem : ShippingItem
{ }
public class ShippingItemPalletTableItem : ShippingItemPallet
{ }
//public class ShippingItemPalletTableItem : ShippingItemPallet { }
public class ProductDtoTableItem : ProductDto
{
//[Newtonsoft.Json.JsonProperty]
@ -45,13 +43,12 @@ public class ShippingItemTable : SignalRDataSourceList<ShippingItemTableItem>
{
private static readonly SignalRCrudTags SignalRCrudTags = new(SignalRTags.GetShippingItems, 0, SignalRTags.AddShippingItem, SignalRTags.UpdateShippingItem, 0);
public ShippingItemTable(AcSignalRClientBase signalRClient, params object[]? contextIds)
: this(signalRClient, SignalRCrudTags, contextIds)
public ShippingItemTable(AcSignalRClientBase signalRClient, IAcLoggerBase? logger, params object[]? contextIds) : this(signalRClient, SignalRCrudTags, logger, contextIds)
{
}
public ShippingItemTable(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, params object[]? contextIds) : base(signalRClient, signalRCrudTags, contextIds)
public ShippingItemTable(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, IAcLoggerBase? logger, params object[]? contextIds) : base(signalRClient, signalRCrudTags, logger, contextIds)
{
}
}
@ -111,7 +108,7 @@ public class OrderDtoTable(FruitBankSignalRClient fruitBankSignalRClient) : AcOb
public abstract class DatabaseTableBase<TDataItem> : SignalRDataSourceObservable<TDataItem> where TDataItem : class, IId<int>
{
protected DatabaseTableBase(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, params object[]? contextIds) : base(signalRClient, signalRCrudTags, contextIds)
protected DatabaseTableBase(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, IAcLoggerBase? logger, params object[]? contextIds) : base(signalRClient, signalRCrudTags, logger, contextIds)
{
}
@ -171,7 +168,7 @@ public class DatabaseClient : DatabaseClientBase
_fruitBankSignalRClient = fruitBankSignalRClient;
AddTable(new ProductDtoTable(_fruitBankSignalRClient));
AddTable(new ShippingItemTable(_fruitBankSignalRClient));
AddTable(new ShippingItemTable(_fruitBankSignalRClient, null));
AddTable(new OrderDtoTable(_fruitBankSignalRClient));
}

View File

@ -2,6 +2,7 @@
@using FruitBank.Common.Dtos
@using FruitBank.Common.Entities
@using FruitBankHybrid.Shared.Components
@using FruitBankHybrid.Shared.Components.Grids.Cargos
@using FruitBankHybrid.Shared.Components.Grids.Partners
@using FruitBankHybrid.Shared.Components.Grids.Shippings
@using FruitBankHybrid.Shared.Databases
@ -25,6 +26,9 @@
<DxTabPage Text="Beszállítók" Visible="@(LoggedInModel.IsAdministrator)">
<GridPartner @ref="gridPartner" Partners="@Partners" IsMasterGrid="true"></GridPartner>
</DxTabPage>
<DxTabPage Text="Fuvarozók" Visible="@(LoggedInModel.IsAdministrator)">
<GridCargoPartner @ref="gridCargoPartner" CargoPartners="CargoPartners" IsMasterGrid="true"></GridCargoPartner>
</DxTabPage>
<DxTabPage Text="Szállítmányok">
<GridShipping @ref="gridShipping" Shippings="@Shippings" Partners="@Partners" IsMasterGrid="true"></GridShipping>
</DxTabPage>

View File

@ -15,6 +15,7 @@ using FruitBankHybrid.Shared.Services.Loggers;
using FruitBankHybrid.Shared.Services.SignalRs;
using Mango.Nop.Core.Loggers;
using Microsoft.AspNetCore.Components;
using FruitBankHybrid.Shared.Components.Grids.Cargos;
namespace FruitBankHybrid.Shared.Pages;
@ -29,6 +30,7 @@ public partial class ShippingsAdmin : ComponentBase
private GridProductDtoTemplate gridProductDtoTemplate;
private GridPartner gridPartner;
private GridCargoPartner gridCargoPartner;
private GridShipping gridShipping;
private GridShippingDocument gridShippingDocument;
private GridShippingItemTemplate gridShippingItemTemplate;
@ -39,6 +41,7 @@ public partial class ShippingsAdmin : ComponentBase
public AcObservableCollection<ShippingItem> ShippingItems { get; set; } = [];
public List<ShippingItemPallet> ShippingItemPallets { get; set; } = [];
public AcObservableCollection<Partner> Partners { get; set; } = [];
public AcObservableCollection<CargoPartner> CargoPartners { get; set; } = [];
public bool AutoCollapseDetailRow { get; set; }

View File

@ -57,25 +57,31 @@ namespace FruitBankHybrid.Shared.Services.SignalRs
}
}
public Task<List<MeasuringModel>?> GetMeasuringModels()
=> GetAllAsync<List<MeasuringModel>>(SignalRTags.GetMeasuringModels);
public Task<List<Partner>?> GetPartners()
=> GetAllAsync<List<Partner>>(SignalRTags.GetPartners);
public Task<List<MeasuringModel>?> GetMeasuringModels() => GetAllAsync<List<MeasuringModel>>(SignalRTags.GetMeasuringModels);
#region Partner
public Task<Partner?> GetPartnerById(int id)
=> GetByIdAsync<Partner?>(SignalRTags.GetPartnerById, id);
public Task<Partner?> AddPartner(Partner partner)
=> PostDataAsync(SignalRTags.AddPartner, partner);
public Task<Partner?> UpdatePartner(Partner partner)
=> PostDataAsync(SignalRTags.UpdatePartner, partner);
public Task<List<Partner>?> GetPartners() => GetAllAsync<List<Partner>>(SignalRTags.GetPartners);
public Task<Partner?> GetPartnerById(int id) => GetByIdAsync<Partner?>(SignalRTags.GetPartnerById, id);
public Task<Partner?> AddPartner(Partner partner) => PostDataAsync(SignalRTags.AddPartner, partner);
public Task<Partner?> UpdatePartner(Partner partner) => PostDataAsync(SignalRTags.UpdatePartner, partner);
#endregion Partner
#region CargoPartner
public Task<List<CargoPartner>?> GetCargoPartners() => GetAllAsync<List<CargoPartner>>(SignalRTags.GetCargoPartners);
public Task<CargoPartner?> GetCargoPartnerById(int id) => GetByIdAsync<CargoPartner?>(SignalRTags.GetCargoPartnerById, id);
public Task<CargoPartner?> AddCargoPartner(CargoPartner cargoPartner) => PostDataAsync(SignalRTags.AddCargoPartner, cargoPartner);
public Task<CargoPartner?> UpdateCargoPartner(CargoPartner cargoPartner) => PostDataAsync(SignalRTags.UpdateCargoPartner, cargoPartner);
#endregion CargoPartner
#region CargoTruck
public Task<List<CargoTruck>?> GetCargoTrucks() => GetAllAsync<List<CargoTruck>>(SignalRTags.GetCargoTrucks);
public Task<CargoTruck?> GetCargoTruckById(int id) => GetByIdAsync<CargoTruck?>(SignalRTags.GetCargoTruckById, id);
public Task<List<CargoTruck>?> GetCargoTrucksByCargoPartnerId(int cargoPartnerId) => GetAllAsync<List<CargoTruck>>(SignalRTags.GetCargoTrucksByCargoPartnerId, [cargoPartnerId]);
public Task<CargoTruck?> AddCargoTruck(CargoTruck cargoTruck) => PostDataAsync(SignalRTags.AddCargoTruck, cargoTruck);
public Task<CargoTruck?> UpdateCargoTruck(CargoTruck cargoTruck) => PostDataAsync(SignalRTags.UpdateCargoTruck, cargoTruck);
#endregion CargoTruck
#region Shipping
public Task<List<Shipping>?> GetShippings()

View File

@ -1,18 +1,19 @@
using System.Collections.ObjectModel;
using AyCode.Core.Helpers;
using AyCode.Core.Interfaces;
using AyCode.Core.Loggers;
using AyCode.Services.Server.SignalRs;
using AyCode.Services.SignalRs;
using System.Collections.ObjectModel;
using System.Diagnostics;
using AyCode.Core.Helpers;
namespace FruitBankHybrid.Shared.Services.SignalRs;
[Serializable]
[DebuggerDisplay("Count = {Count}")]
public class SignalRDataSourceList<TDataItem>(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, params object[]? contextIds)
: AcSignalRDataSource<TDataItem, int, List<TDataItem>>(signalRClient, signalRCrudTags, contextIds) where TDataItem : class, IId<int>;
public class SignalRDataSourceList<TDataItem>(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, IAcLoggerBase? logger, params object[]? contextIds)
: AcSignalRDataSource<TDataItem, int, List<TDataItem>>(signalRClient, signalRCrudTags, logger, contextIds) where TDataItem : class, IId<int>;
[Serializable]
[DebuggerDisplay("Count = {Count}")]
public class SignalRDataSourceObservable<TDataItem>(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, params object[]? contextIds)
: AcSignalRDataSource<TDataItem, int, AcObservableCollection<TDataItem>>(signalRClient, signalRCrudTags, contextIds) where TDataItem : class, IId<int>;
public class SignalRDataSourceObservable<TDataItem>(AcSignalRClientBase signalRClient, SignalRCrudTags signalRCrudTags, IAcLoggerBase? logger, params object[]? contextIds)
: AcSignalRDataSource<TDataItem, int, AcObservableCollection<TDataItem>>(signalRClient, signalRCrudTags, logger, contextIds) where TDataItem : class, IId<int>;

View File

@ -38,7 +38,7 @@
"AcBinaryHubProtocol": {
"ProtocolMode": "AsyncSegment",
"BufferSize": 4096,
"FlushPolicy": "DoubleBuffered",
"FlushPolicy": "Coalesced",
"FlushTimeout": "00:00:10"
}
}

View File

@ -38,7 +38,7 @@
"AcBinaryHubProtocol": {
"ProtocolMode": "AsyncSegment",
"BufferSize": 4096,
"FlushPolicy": "DoubleBuffered",
"FlushPolicy": "Coalesced",
"FlushTimeout": "00:00:10"
}
}

View File

@ -38,7 +38,7 @@
"AcBinaryHubProtocol": {
"ProtocolMode": "AsyncSegment",
"BufferSize": 4096,
"FlushPolicy": "DoubleBuffered",
"FlushPolicy": "Coalesced",
"FlushTimeout": "00:00:10"
}
}