using DevExpress.ExpressApp.ConditionalAppearance; using DevExpress.ExpressApp.Model; using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl; using DevExpress.Persistent.Validation; using DevExpress.Xpo; using DurnyklyYol.Module.Services; using Microsoft.Extensions.DependencyInjection; using System.ComponentModel; namespace DurnyklyYol.Module.BusinessObjects { [DefaultClassOptions, NavigationItem("Transportation")] [ImageName("Shipment")] [DefaultProperty(nameof(No))] [Appearance("CargoRedBackground", AppearanceItemType = "ViewItem", TargetItems = "Credit", Criteria = "TotalСredit > 0", BackColor = "Red", FontColor = "White")] [Appearance("CargoStrikeBackground", AppearanceItemType = "ViewItem", TargetItems = "*", Criteria = "TotalСredit = 0 And TotalPriceAmount >0 ", FontStyle = DevExpress.Drawing.DXFontStyle.Strikeout)] public class Cargo : BaseObject { // Inherit from a different class to provide a custom primary key, concurrency and deletion behavior, etc. (https://documentation.devexpress.com/eXpressAppFramework/CustomDocument113146.aspx). // Use CodeRush to create XPO classes and properties with a few keystrokes. // https://docs.devexpress.com/CodeRushForRoslyn/118557 public Cargo(Session session) : base(session) { } private Point originalCurrentPoint; protected override void OnLoaded() { base.OnLoaded(); originalCurrentPoint = CurrentPoint; } protected override void OnSaving() { base.OnSaving(); if (Session is not NestedUnitOfWork && (Session.DataLayer != null) && Session.IsNewObject(this) && (Session.ObjectLayer is SimpleObjectLayer) //OR //&& !(Session.ObjectLayer is DevExpress.ExpressApp.Security.ClientServer.SecuredSessionObjectLayer) ) { if (string.IsNullOrEmpty(No)) { int nextSequence = DistributedIdGeneratorHelper.Generate( Session.DataLayer, this.GetType().FullName, "ERPrefix" ); No = string.Format("KA-{0:D6}", nextSequence); } } } protected override void OnSaved() { base.OnSaved(); if (CurrentPoint != null && CurrentPoint != originalCurrentPoint) { var notification = Session.ServiceProvider.GetRequiredService(); System.Threading.Tasks.Task.Run(async () => await notification.NotifyClients(this)); } } double totalWeight; string no; //CargoState state; Point currentPoint; DateTime? arrivedAt; DateTime? startedAt; Carrier carrier; Route route; [ReadOnly(true), VisibleInDetailView(false), Index(0)] [Size(SizeAttribute.DefaultStringMappingFieldSize), Indexed, RuleUniqueValue] public string No { get => no; set => SetPropertyValue(nameof(No), ref no, value); } //TODO current root bilen deneshdirip al public CargoState State { get { if (CurrentPoint == null || Route == null || Route.Points.Count == 0) { return CargoState.Warehouse; } var lastPoint = Route.Points.OrderBy(o => o.Order).Last(); if (lastPoint != null && CurrentPoint != null && lastPoint.Oid == CurrentPoint.Oid) { return CargoState.Arrived; } return CargoState.InTransit; } //set => SetPropertyValue(nameof(State), ref state, value); } [ModelDefault("DisplayFormat", "{0:g}"), ModelDefault("EditMask", "g")] public DateTime? StartedAt { get => startedAt; set => SetPropertyValue(nameof(StartedAt), ref startedAt, value); } [ModelDefault("DisplayFormat", "{0:g}"), ModelDefault("EditMask", "g")] public DateTime? ArrivedAt { get => arrivedAt; set => SetPropertyValue(nameof(ArrivedAt), ref arrivedAt, value); } public double TotalWeight { get => totalWeight; set => SetPropertyValue(nameof(TotalWeight), ref totalWeight, value); } //[Persistent(nameof(TotalPriceAmount))] //private decimal totalPriceAmount; //[PersistentAlias(nameof(totalPriceAmount))] [ModelDefault("DisplayFormat", "${0:#,##0.00}")] public decimal TotalPriceAmount => Goods.Sum(gs => gs.Price); [ModelDefault("DisplayFormat", "${0:#,##0.00}")] public decimal TotalExpenseAmount => Expenses.Sum(es => es.Amount); [ModelDefault("DisplayFormat", "${0:#,##0.00}")] public decimal PayedTotal => Goods.Sum(gs => gs.TotalPayment); [ModelDefault("DisplayFormat", "${0:#,##0.00}")] public decimal TotalСredit => Goods.Sum(gs => gs.Credit); [ModelDefault("DisplayFormat", "${0:#,##0.00}")] public decimal ExpectedProfit => TotalPriceAmount - TotalExpenseAmount; [ModelDefault("DisplayFormat", "${0:#,##0.00}")] public decimal CurrentProfit => PayedTotal - TotalExpenseAmount; [RuleRequiredField(DefaultContexts.Save), ImmediatePostData] public Route Route { get => route; set { if (SetPropertyValue(nameof(Route), ref route, value) && !IsLoading && !IsSaving && value is not null) { CurrentPoint = null; OnChanged(nameof(CurrentPoint)); } } } private void populateCargoPoints() { //todo initialize cargo route points //current point is taken from cargo route points where date is not null } [Browsable(false)] public XPCollection AvailablePoints { get { if (Route is null) return new XPCollection(Session); var points = Route.Points .OrderBy(or => or.Order) .Select(sl => sl.Point) .ToList(); return new XPCollection(Session, points); } } [ImmediatePostData, DataSourceProperty(nameof(AvailablePoints))] public Point CurrentPoint { get => currentPoint; set => SetPropertyValue(nameof(CurrentPoint), ref currentPoint, value); } [RuleRequiredField(DefaultContexts.Save)] public Carrier Carrier { get => carrier; set => SetPropertyValue(nameof(Carrier), ref carrier, value); } [Association("Cargo-Goods")] public XPCollection Goods { get { return GetCollection(nameof(Goods)); } } [Association("Cargo-Expenses"), Aggregated] public XPCollection Expenses { get { return GetCollection(nameof(Expenses)); } } [Association, Aggregated] public XPCollection CargoPoints { get { return GetCollection(nameof(CargoPoints)); } } } public enum CargoState { Warehouse, InTransit, Arrived } }