Add project files.

This commit is contained in:
merdan 2024-09-02 15:07:25 +05:00
parent 6ce91de8a9
commit 9a69b818bd
112 changed files with 6262 additions and 0 deletions

3
.filenesting.json Normal file
View File

@ -0,0 +1,3 @@
{
"help":"https://go.microsoft.com/fwlink/?linkid=866610"
}

View File

@ -0,0 +1,13 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "8.0.8",
"commands": [
"dotnet-ef"
],
"rollForward": false
}
}
}

View File

@ -0,0 +1,21 @@
YOUR FEEDBACK MATTERS
If you are an active Universal subscriber (or planning to become one), and are interested in additional Web API Service endpoints:
- check the state of input data with 10+ of built-in and unlimited custom validation rules;
- download PDF, RTF, etc. from Office documents or Mail Merge templates (RichTextMailMergeData) based on filtered data in databases;
- download PDF, RTF, etc. from Dashboard templates (DashboardData) based on filtered data in databases;
- etc.
Please share your specific project requirements with us OR tell us how our Web API Service works for you:
https://www.devexpress.com/go/XAF_WebAPI_Feedback.aspx - THANKS!
We want to validate a few hypotheses using your feedback and also share our implementation considerations with you (to finalize this for production).
Relevant Documentation
Validation Module
https://docs.devexpress.com/eXpressAppFramework/113684/
Office Module
https://docs.devexpress.com/eXpressAppFramework/400003/
Dashboards Module
https://docs.devexpress.com/eXpressAppFramework/117449/xtensions

View File

@ -0,0 +1,16 @@
Folder Description
The "api/MediaFiles/" endpoints are intended to download BLOB data stored in databases (aka File Attachments).
You can download data from FileData, MediaDataObject, Image or byte array properties declared in your data models.
These additional benefits of our Web API Service ship as part of the DevExpress Universal Subscription (https://www.devexpress.com/buy/net/).
YOUR FEEDBACK MATTERS
Please tell us how our Web API Service works for you: https://www.devexpress.com/go/XAF_WebAPI_Feedback.aspx - THANKS!
Relevant Documentation
Obtain BLOB Data from a Web API Controller Endpoint
https://docs.devexpress.com/eXpressAppFramework/404207/
File Attachments Module
https://docs.devexpress.com/eXpressAppFramework/112781/

View File

@ -0,0 +1,19 @@
Folder Description
The "api/Localization/" endpoints are intended to obtain localized UI strings through HTTP requests to a Web API service.
You can use the localized UI strings in your custom application that uses the XAF Web API as a backend.
These additional benefits of our Web API Service ship as part of the DevExpress Universal Subscription (https://www.devexpress.com/buy/net/).
YOUR FEEDBACK MATTERS
Please tell us how our Web API Service works for you: https://www.devexpress.com/go/XAF_WebAPI_Feedback.aspx - THANKS!
Relevant Documentation
Get Localization Strings from a Web API Controller Endpoint
https://docs.devexpress.com/eXpressAppFramework/403982/
Localization Module
https://docs.devexpress.com/eXpressAppFramework/113298/
Model Editor
https://docs.devexpress.com/eXpressAppFramework/112582

View File

@ -0,0 +1,17 @@
Folder Description
The "api/Report/" endpoints are intended to download PDF, RTF, etc. from report templates (ReportDatav2) based on filtered data in databases.
Each ReportDatav2 container is stored in your database and links to an XtraReport, and report data sources, and data models that you designed in Visual Studio.
You can pass a report container identifier, data source criteria, export format, and other parameters to your endpoints.
These additional benefits of our Web API Service ship as part of the DevExpress Universal Subscription (https://www.devexpress.com/buy/net/).
YOUR FEEDBACK MATTERS
Please tell us how our Web API Service works for you: https://www.devexpress.com/go/XAF_WebAPI_Feedback.aspx - THANKS!
Relevant Documentation
Obtain a Report from a Web API Controller Endpoint
https://docs.devexpress.com/eXpressAppFramework/404176/
Reports V2 Module
https://docs.devexpress.com/eXpressAppFramework/113591/

View File

@ -0,0 +1,87 @@
#nullable enable
using DevExpress.ExpressApp.ReportsV2.Services;
using DevExpress.ExpressApp.ReportsV2;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
using DevExpress.XtraPrinting;
using DevExpress.XtraReports.UI;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
namespace DurnyklyYol.WebApi.Reports;
[Authorize]
[Route("api/[controller]")]
// This is a WebApi Reports controller sample.
public class ReportController : ControllerBase {
private readonly IReportExportService service;
public ReportController(IReportExportService reportExportService) {
service = reportExportService;
}
private void ApplyParametersFromQuery(XtraReport report) {
foreach(var parameter in report.Parameters) {
var queryParam = Request.Query[parameter.Description];
if(queryParam.Count > 0) {
parameter.Value = queryParam.First();
}
}
}
private SortProperty[]? LoadSortPropertiesFromQuery() {
if(Request.Query.Keys.Contains("sortProperty")) {
var queryParam = Request.Query["sortProperty"];
SortProperty[] result = new SortProperty[queryParam.Count];
for(int i = 0; i < queryParam.Count; i++) {
string[] paramData = queryParam[i]!.Split(",");
result[i] = new SortProperty(paramData[0], (SortingDirection)Enum.Parse(typeof(SortingDirection), paramData[1]));
}
return result;
}
return null;
}
private async Task<object> GetReportContentAsync(XtraReport report, ExportTarget fileType) {
Stream ms = await service.ExportReportAsync(report, fileType);
HttpContext.Response.RegisterForDispose(ms);
return File(ms, service.GetContentType(fileType), $"{report.DisplayName}.{service.GetFileExtension(fileType)}");
}
[HttpGet("DownloadByKey({key})")]
[SwaggerOperation("Gets the contents of a report specified by its key in the specified file format filtered based on the specified condition.", "For more information, refer to the following article: <a href='https://docs.devexpress.com/eXpressAppFramework/404176/backend-web-api-service/obtain-a-report-from-a-web-api-controller-endpoint'>Obtain a Report from a Web API Controller Endpoint</a>.")]
public async Task<object> DownloadByKey(
[SwaggerParameter("A primary key value that uniquely identifies a report. <br/>Example: '83978d7f-82b7-4380-979a-08db4587a66b'")]
string key,
[FromQuery, SwaggerParameter("The file type in which to download the report.")]
ExportTarget fileType = ExportTarget.Pdf,
[FromQuery, SwaggerParameter("A condition used to filter the report's data. <br/>Example: \"[FirstName] = 'Aaron'\"")]
string? criteria = null) {
using var report = service.LoadReport<ReportDataV2>(key);
ApplyParametersFromQuery(report);
SortProperty[]? sortProperties = LoadSortPropertiesFromQuery();
service.SetupReport(report, criteria, sortProperties);
return await GetReportContentAsync(report, fileType);
}
[HttpGet("DownloadByName({displayName})")]
[SwaggerOperation("Gets the contents of a report specified by its display name in the specified file format filtered based on the specified condition.", "For more information, refer to the following article: <a href='https://docs.devexpress.com/eXpressAppFramework/404176/backend-web-api-service/obtain-a-report-from-a-web-api-controller-endpoint'>Obtain a Report from a Web API Controller Endpoint</a>.")]
public async Task<object> DownloadByName(
[SwaggerParameter("The display name of a report to download. <br/>Example: 'Employee List Report'")]
string displayName,
[FromQuery, SwaggerParameter("The file type in which to download the report.")]
ExportTarget fileType = ExportTarget.Pdf,
[FromQuery, SwaggerParameter("A condition used to filter the report's data. <br/>Example: \"[FirstName] = 'Aaron'\"")]
string? criteria = null) {
if(!string.IsNullOrEmpty(displayName)) {
using var report = service.LoadReport<ReportDataV2>(data => data.DisplayName == displayName);
ApplyParametersFromQuery(report);
SortProperty[]? sortProperties = LoadSortPropertiesFromQuery();
service.SetupReport(report, criteria, sortProperties);
return await GetReportContentAsync(report, fileType);
}
return NotFound();
}
}
#nullable restore

View File

@ -0,0 +1,32 @@
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.Security.Authentication;
using DevExpress.ExpressApp.Security.Authentication.ClientServer;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
namespace DurnyklyYol.WebApi.JWT;
[ApiController]
[Route("api/[controller]")]
// This is a JWT authentication service sample.
public class AuthenticationController : ControllerBase {
readonly IAuthenticationTokenProvider tokenProvider;
public AuthenticationController(IAuthenticationTokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
}
[HttpPost("Authenticate")]
[SwaggerOperation("Checks if the user with the specified logon parameters exists in the database. If it does, authenticates this user.", "Refer to the following help topic for more information on authentication methods in the XAF Security System: <a href='https://docs.devexpress.com/eXpressAppFramework/119064/data-security-and-safety/security-system/authentication'>Authentication</a>.")]
public IActionResult Authenticate(
[FromBody]
[SwaggerRequestBody(@"For example: <br /> { ""userName"": ""Admin"", ""password"": """" }")]
AuthenticationStandardLogonParameters logonParameters
) {
try {
return Ok(tokenProvider.Authenticate(logonParameters));
}
catch(AuthenticationException ex) {
return Unauthorized(ex.GetJson());
}
}
}

View File

@ -0,0 +1,37 @@
using System.IdentityModel.Tokens.Jwt;
using System.Runtime.ExceptionServices;
using System.Security.Claims;
using System.Text;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.Security.Authentication.ClientServer;
using Microsoft.IdentityModel.Tokens;
namespace DurnyklyYol.WebApi.JWT;
public class JwtTokenProviderService : IAuthenticationTokenProvider {
readonly SignInManager signInManager;
readonly IConfiguration configuration;
public JwtTokenProviderService(SignInManager signInManager, IConfiguration configuration) {
this.signInManager = signInManager;
this.configuration = configuration;
}
public string Authenticate(object logonParameters) {
var result = signInManager.AuthenticateByLogonParameters(logonParameters);
if(result.Succeeded) {
var issuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Authentication:Jwt:IssuerSigningKey"]));
var token = new JwtSecurityToken(
//issuer: configuration["Authentication:Jwt:Issuer"],
//audience: configuration["Authentication:Jwt:Audience"],
claims: result.Principal.Claims,
expires: DateTime.Now.AddDays(2),
signingCredentials: new SigningCredentials(issuerSigningKey, SecurityAlgorithms.HmacSha256)
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
if(result.Error is IUserFriendlyException) {
ExceptionDispatchInfo.Throw(result.Error);
}
throw new AuthenticationException("Internal server error");
}
}

View File

@ -0,0 +1,21 @@
Folder Description
The "api/Authentication/" endpoint is intended to authenticate users based on logon parameters (a name and password).
The generated JWT authentication tokens are used to access API Controllers securely.
YOUR FEEDBACK MATTERS
Please tell us how our Web API Service works for you: https://www.devexpress.com/go/XAF_WebAPI_Feedback.aspx - THANKS!
Relevant Documentation
Use the Swagger UI to Test the JWT Authentication
https://docs.devexpress.com/eXpressAppFramework/403504/
Access Security System in a Web API Controller Endpoint
https://docs.devexpress.com/eXpressAppFramework/403861/
Overview of ASP.NET Core authentication
https://learn.microsoft.com/en-us/aspnet/core/security/authentication/
Security System Module
https://docs.devexpress.com/eXpressAppFramework/113591/

View File

@ -0,0 +1,11 @@
<Router AppAssembly="@typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(DevExpress.ExpressApp.Blazor.BlazorApplication).Assembly }">
<Found Context="routeData">
<RouteView RouteData="@routeData" />
</Found>
<NotFound>
<LayoutView>
<PageTitle>Not found</PageTitle>
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>

View File

@ -0,0 +1,49 @@
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.ApplicationBuilder;
using DevExpress.ExpressApp.Blazor;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.Security.ClientServer;
using DevExpress.ExpressApp.SystemModule;
using DevExpress.ExpressApp.Xpo;
using DurnyklyYol.Blazor.Server.Services;
namespace DurnyklyYol.Blazor.Server;
public class DurnyklyYolBlazorApplication : BlazorApplication {
public DurnyklyYolBlazorApplication() {
ApplicationName = "DurnyklyYol";
CheckCompatibilityType = DevExpress.ExpressApp.CheckCompatibilityType.DatabaseSchema;
DatabaseVersionMismatch += DurnyklyYolBlazorApplication_DatabaseVersionMismatch;
}
protected override void OnSetupStarted() {
base.OnSetupStarted();
#if DEBUG
if(System.Diagnostics.Debugger.IsAttached && CheckCompatibilityType == CheckCompatibilityType.DatabaseSchema) {
DatabaseUpdateMode = DatabaseUpdateMode.UpdateDatabaseAlways;
}
#endif
}
private void DurnyklyYolBlazorApplication_DatabaseVersionMismatch(object sender, DatabaseVersionMismatchEventArgs e) {
#if EASYTEST
e.Updater.Update();
e.Handled = true;
#else
if(System.Diagnostics.Debugger.IsAttached) {
e.Updater.Update();
e.Handled = true;
}
else {
string message = "The application cannot connect to the specified database, " +
"because the database doesn't exist, its version is older " +
"than that of the application or its schema does not match " +
"the ORM data model structure. To avoid this error, use one " +
"of the solutions from the https://www.devexpress.com/kb=T367835 KB Article.";
if(e.CompatibilityError != null && e.CompatibilityError.Exception != null) {
message += "\r\n\r\nInner exception: " + e.CompatibilityError.Exception.Message;
}
throw new InvalidOperationException(message);
}
#endif
}
}

View File

@ -0,0 +1,38 @@
using System.ComponentModel;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Model;
using DevExpress.ExpressApp.Editors;
using DevExpress.ExpressApp.Actions;
using DevExpress.ExpressApp.Updating;
using DevExpress.ExpressApp.Model.Core;
using DevExpress.ExpressApp.Model.DomainLogics;
using DevExpress.ExpressApp.Model.NodeGenerators;
using DevExpress.Persistent.BaseImpl;
namespace DurnyklyYol.Blazor.Server;
[ToolboxItemFilter("Xaf.Platform.Blazor")]
// For more typical usage scenarios, be sure to check out https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.ModuleBase.
public sealed class DurnyklyYolBlazorModule : ModuleBase {
//private void Application_CreateCustomModelDifferenceStore(object sender, CreateCustomModelDifferenceStoreEventArgs e) {
// e.Store = new ModelDifferenceDbStore((XafApplication)sender, typeof(ModelDifference), true, "Blazor");
// e.Handled = true;
//}
private void Application_CreateCustomUserModelDifferenceStore(object sender, CreateCustomModelDifferenceStoreEventArgs e) {
e.Store = new ModelDifferenceDbStore((XafApplication)sender, typeof(ModelDifference), false, "Blazor");
e.Handled = true;
}
public DurnyklyYolBlazorModule() {
}
public override IEnumerable<ModuleUpdater> GetModuleUpdaters(IObjectSpace objectSpace, Version versionFromDB) {
return ModuleUpdater.EmptyModuleUpdaters;
}
public override void Setup(XafApplication application) {
base.Setup(application);
// Uncomment this code to store the shared model differences (administrator settings in Model.XAFML) in the database.
// For more information, refer to the following topic: https://docs.devexpress.com/eXpressAppFramework/113698/
//application.CreateCustomModelDifferenceStore += Application_CreateCustomModelDifferenceStore;
application.CreateCustomUserModelDifferenceStore += Application_CreateCustomUserModelDifferenceStore;
}
}

View File

@ -0,0 +1,86 @@
using DevExpress.ExpressApp.Core;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.WebApi.Services;
using DurnyklyYol.Blazor.Server.DTO;
using DurnyklyYol.Module.BusinessObjects;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace DurnyklyYol.Blazor.Server.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CargoController : ControllerBase
{
private readonly INonSecuredObjectSpaceFactory _nonSecuredObjectSpaceFactory;
public CargoController(INonSecuredObjectSpaceFactory nonSecuredObjectSpaceFactory) => _nonSecuredObjectSpaceFactory = nonSecuredObjectSpaceFactory;
[HttpGet("Route/{cargoId}")]
public IActionResult GetRoute(Guid cargoId)
{
try
{
using var objectSpace = _nonSecuredObjectSpaceFactory.CreateNonSecuredObjectSpace(typeof(Cargo));
var cargo = objectSpace.GetObjectByKey<Cargo>(cargoId);
if (cargo == null)
{
return NotFound();
}
var route = objectSpace.GetObjectsQuery<Module.BusinessObjects.Route>()
.Where(wh => wh.Oid == cargo.Route.Oid)
.Select(sl => new
{
StartName = sl.StartPoint.Name,
Startpoint = sl.StartPoint.Point,
DestName = sl.DestinationPoint.Name,
Destpoint = sl.DestinationPoint.Point,
Points = sl.Points.OrderBy(ob => ob.Order).Select(p => p.Point)
})
.FirstOrDefault();
if (route == null)
{
return NotFound();
}
var points = route.Points.Select(p => new PointDto
{
Name = p.Name,
Lat = p.Latitude,
Long = p.Longitude,
IsCurrent = cargo.CurrentPoint.Oid == p.Oid,
}).ToList();
points.Insert(0, new PointDto
{
Name = route.StartName,
Lat = route.Startpoint?.Latitude ?? 0,
Long = route.Startpoint?.Longitude ?? 0,
IsCurrent = cargo.CurrentPoint.Oid == route.Startpoint?.Oid,
DateAt = cargo.StartedAt
});
points.Add(new PointDto
{
Name = route.DestName,
Lat = route.Destpoint?.Latitude ?? 0,
Long = route.Destpoint?.Longitude ?? 0,
IsCurrent = cargo.CurrentPoint.Oid == route.Destpoint?.Oid,
DateAt = cargo.ArrivedAt
});
return Ok(points);
}
catch (Exception ex) {
return StatusCode(500, ex.Message);
}
}
}
}

View File

@ -0,0 +1,44 @@
using Microsoft.AspNetCore.Mvc;
using DevExpress.ExpressApp.Security;
using DevExpress.Persistent.BaseImpl.PermissionPolicy;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.SystemModule;
using DevExpress.Persistent.Base;
using DevExpress.ExpressApp.WebApi;
using System.Linq;
using DevExpress.ExpressApp.Core;
using DurnyklyYol.Module.BusinessObjects;
using Microsoft.AspNetCore.Authorization;
using DevExpress.ExpressApp.WebApi.Services;
namespace DurnyklyYol.Blazor.Server.Controllers
{
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class ClientController : Microsoft.AspNetCore.Mvc.ControllerBase
{
private readonly IDataService dataService;
private readonly ISecurityProvider securityProvider;
public ClientController(IDataService dataService, ISecurityProvider securityProvider)
{
this.dataService = dataService;
this.securityProvider = securityProvider;
}
[HttpGet(nameof(GetClient))]
[Authorize]
public IActionResult GetClient()
{
var objectSpace = dataService.GetObjectSpace<Client>();
var userID = (Guid)securityProvider.GetSecurity().UserId;
var clients = objectSpace.GetObjectsQuery<Client>()
.Select(sl => new { Fulname = sl.FullName, Oid = sl.Oid, PhoneNo = sl.Telefon})
.First(cl => cl.Oid == userID);
return Ok(clients);
}
}
}

View File

@ -0,0 +1,81 @@
using DevExpress.CodeParser;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.WebApi.Services;
using DurnyklyYol.Blazor.Server.DTO;
using DurnyklyYol.Module.BusinessObjects;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DurnyklyYol.Blazor.Server.Controllers
{
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class GoodsController : ControllerBase
{
private readonly IDataService dataService;
private readonly ISecurityProvider securityProvider;
public GoodsController(IDataService dataService, ISecurityProvider securityProvider)
{
this.dataService = dataService;
this.securityProvider = securityProvider;
}
[Authorize]
[HttpGet]
public IActionResult Get([FromQuery] int pageNumber = 1, [FromQuery] int pageSize = 10, [FromQuery] GoodsState? state = null)
{
var objectSpace = dataService.GetObjectSpace<Goods>();
var userID = (Guid)securityProvider.GetSecurity().UserId;
var goodsQuery = objectSpace.GetObjectsQuery<Goods>()
.Where(cl => cl.Client.Oid == userID)
.Select(sl => new GoodsDto {
No = sl.No,
Oid = sl.Oid,
Name = sl.Name,
PlacesCount = sl.PlaceCount,
Volume = sl.Volume,
ShopNo = sl.ShopNo,
Carrier = sl.Cargo.Carrier.Number,
From = sl.Cargo.StartsFrom,
To = sl.Cargo.DestinationTo,
ClientId = sl.Client.Oid,
DepartedAt = sl.Cargo.StartedAt,
Depth = sl.Depth,
Width = sl.Width,
Height = sl.Height,
CargoId = sl.Cargo.Oid,
CargoState = sl.Cargo.State,
State = sl.State,
Price = sl.Price,
Image1 = sl.Image1 != null ? string.Format("/FileData/{0}-{1}", sl.Image1.Oid, sl.Image1.FileName) : "",
Image2 = sl.Image2 != null ? string.Format("/FileData/{0}-{1}", sl.Image2.Oid, sl.Image2.FileName) : "",
Image3 = sl.Image3 != null ? string.Format("/FileData/{0}-{1}", sl.Image3.Oid, sl.Image3.FileName) : "",
});
if (state != null) {
goodsQuery.Where(wh => wh.State == state);
}
var totalRecords = goodsQuery.Count();
var goods = goodsQuery
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToList();
var response = new
{
TotalRecords = totalRecords,
PageNumber = pageNumber,
PageSize = pageSize,
Data = goods
};
return Ok(response);
}
}
}

View File

@ -0,0 +1,36 @@
namespace DurnyklyYol.Blazor.Server.Controllers
{
partial class GoodsImageUploadController
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,57 @@
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.ExpressApp.Blazor.Components.Models;
using DevExpress.ExpressApp.Editors;
using DevExpress.ExpressApp.Layout;
using DevExpress.ExpressApp.Model.NodeGenerators;
using DevExpress.ExpressApp.SystemModule;
using DevExpress.ExpressApp.Templates;
using DevExpress.ExpressApp.Utils;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.Validation;
using DurnyklyYol.Module.BusinessObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevExpress.ExpressApp.Blazor.Editors.Adapters;
using DevExpress.ExpressApp.Blazor.SystemModule;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Xpo;
using Microsoft.AspNetCore.Components;
namespace DurnyklyYol.Blazor.Server.Controllers
{
// For more typical usage scenarios, be sure to check out https://documentation.devexpress.com/eXpressAppFramework/clsDevExpressExpressAppViewControllertopic.aspx.
public partial class GoodsImageUploadController : ViewController<DetailView>
{
// Use CodeRush to create Controllers and Actions with a few keystrokes.
// https://docs.devexpress.com/CodeRushForRoslyn/403133/
public GoodsImageUploadController()
{
InitializeComponent();
TargetObjectType = typeof(Goods);
// Target required Views (via the TargetXXX properties) and create their Actions.
}
protected override void OnActivated()
{
base.OnActivated();
// Perform various tasks depending on the target View.
if (View is DetailView detailView && detailView.CurrentObject is Goods goods)
{
}
}
protected override void OnViewControlsCreated()
{
base.OnViewControlsCreated();
// Access and customize the target View control.
}
protected override void OnDeactivated()
{
// Unsubscribe from previously subscribed events and release other references and resources.
base.OnDeactivated();
}
}
}

View File

@ -0,0 +1,25 @@
Folder Description
The "Controllers" project folder is intended for storing Blazor-specific Controller classes
that can change the default XAF application flow and add new features.
Relevant Documentation
Controllers and Actions
https://docs.devexpress.com/eXpressAppFramework/112623
Implement Custom Controllers
https://docs.devexpress.com/eXpressAppFramework/112621
Define the Scope of Controllers and Actions
https://docs.devexpress.com/eXpressAppFramework/113103
Ways to Show a View
https://docs.devexpress.com/eXpressAppFramework/112803
Ways to Implement Business Logic
https://docs.devexpress.com/eXpressAppFramework/113710
Debugging, Unit and Functional Testing
https://docs.devexpress.com/eXpressAppFramework/112572

View File

@ -0,0 +1,11 @@
namespace DurnyklyYol.Blazor.Server.DTO
{
public class CargoDto
{
public string No { get; set; }
public PointDto Start { get; set; }
public PointDto End { get; set; }
public IEnumerable<PointDto> Points { get; set; }
}
}

View File

@ -0,0 +1,31 @@
using DurnyklyYol.Module.BusinessObjects;
namespace DurnyklyYol.Blazor.Server.DTO
{
public class GoodsDto
{
public Guid Oid { get; set; }
public Guid ClientId { get; set; }
public Guid CargoId { get; set; }
public GoodsState State { get; set; }
public CargoState CargoState { get; set; }
public string No { get; set; }
public string Name { get; set; }
public string ShopNo { get; set; }
public double Volume { get; set; }
public uint PlacesCount { get; set; }
public string Carrier { get; set; }
public string From { get; set; }
public string To { get; set; }
public DateTime? DepartedAt { get; set; }
public uint Depth { get; set; }
public uint Width { get; set; }
public uint Height { get; set; }
public decimal Price { get; set; }
public string Image1 { get; set; }
public string Image2 { get; set; }
public string Image3 { get; set; }
}
}

View File

@ -0,0 +1,12 @@
namespace DurnyklyYol.Blazor.Server.DTO
{
public class PointDto
{
public string Name { get; set; }
public double Lat { get; set; }
public double Long { get; set; }
public bool IsCurrent { get; set; }
public DateTime? DateAt { get; set; }
}
}

View File

@ -0,0 +1,56 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<Deterministic>false</Deterministic>
<AssemblyVersion>1.0.*</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<Configurations>Debug;Release;EasyTest</Configurations>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Content Remove="GoodsImageUpload.razor" />
</ItemGroup>
<ItemGroup>
<None Remove="Model.xafml" />
<None Remove="Model_tk-TM.xafml" />
</ItemGroup>
<ItemGroup>
<Content Include="Model.xafml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Model_tk-TM.xafml">
<DependentUpon>Model.xafml</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="DevExpress.Drawing.Skia" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Api.Xpo.All" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Blazor" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.CodeAnalysis" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.FileAttachment.Blazor" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.ReportsV2" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.ReportsV2.Blazor" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Security.AspNetCore.Xpo" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Security.Xpo" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Validation" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Validation.Blazor" Version="24.1.4" />
<PackageReference Include="Npgsql" Version="8.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DurnyklyYol.Module\DurnyklyYol.Module.csproj" />
</ItemGroup>
<ItemGroup>
<UpToDateCheckInput Remove="GoodsImageUpload.razor" />
</ItemGroup>
<ItemGroup>
<_ContentIncludedByDefault Remove="GoodsImageUpload.razor" />
</ItemGroup>
<ItemGroup>
<None Include="GoodsImageUpload.razor" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,17 @@
using DevExpress.ExpressApp.Blazor.Editors;
using DevExpress.ExpressApp.Editors;
using DevExpress.ExpressApp.Model;
using Microsoft.AspNetCore.Components;
namespace DurnyklyYol.Blazor.Server.Editors
{
[PropertyEditor(typeof(string), "GoodsImageUploadPropertyEditor", false)]
public class GoodsImageUploadPropertyEditor: BlazorPropertyEditorBase
{
public GoodsImageUploadPropertyEditor(Type objectType, IModelMemberViewItem model)
: base(objectType, model)
{
}
}
}

View File

@ -0,0 +1,25 @@
Folder Description
This project folder is intended for storing custom Blazor List Editors,
Property Editors and View Items.
Relevant Documentation
Using a Custom Control that is not Integrated by Default
https://docs.devexpress.com/eXpressAppFramework/113610
Ways to Access UI Elements and Their Controls
https://docs.devexpress.com/eXpressAppFramework/120092
Views
https://docs.devexpress.com/eXpressAppFramework/112611
List Editors
https://docs.devexpress.com/eXpressAppFramework/113189
View Items
https://docs.devexpress.com/eXpressAppFramework/112612
Debugging, Unit and Functional Testing
https://docs.devexpress.com/eXpressAppFramework/112572

View File

@ -0,0 +1,40 @@
<!-- GoodsImageUpload.razor -->
@page "/upload-goods-images"
@inject IObjectSpace ObjectSpace
@inject IWebHostEnvironment Environment
<InputFile OnChange="HandleFileSelected" multiple />
@code {
[Parameter]
public Goods Goods { get; set; }
private async Task HandleFileSelected(InputFileChangeEventArgs e)
{
var files = e.GetMultipleFiles();
foreach (var file in files)
{
var imageName = $"{Guid.NewGuid()}_{file.Name}";
var path = Path.Combine(Environment.WebRootPath, "uploads", imageName);
Directory.CreateDirectory(Path.GetDirectoryName(path));
using (var fileStream = new FileStream(path, FileMode.Create))
{
await file.OpenReadStream().CopyToAsync(fileStream);
}
var imageUrl = $"uploads/{imageName}";
var goodsImage = ObjectSpace.CreateObject<GoodsImage>();
goodsImage.Goods = Goods;
goodsImage.ImageUrl = imageUrl;
Goods.Images.Add(goodsImage);
}
ObjectSpace.CommitChanges();
}
}

View File

@ -0,0 +1,12 @@
Folder Description
The "Images" project folder is intended for storing custom image files.
Relevant Documentation
Add and Override Images
https://docs.devexpress.com/eXpressAppFramework/112792
Assign a Custom Image
https://docs.devexpress.com/eXpressAppFramework/112744

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<Application>
<BOModel>
<Class Name="DurnyklyYol.Module.BusinessObjects.Contact" Caption="Kontakt">
<OwnMembers>
<Member Name="Name" Caption="Ady" />
<Member Name="Number" Caption="Belgisi" />
</OwnMembers>
</Class>
</BOModel>
<NavigationItems>
<Items>
<Item Id="Default">
<Items>
<Item Id="Contact_ListView" Caption="Kontaktlarymyz" />
</Items>
</Item>
</Items>
</NavigationItems>
<Options UIType="TabbedMDI" RestoreTabbedMdiLayout="False" ShowTabImage="True" />
<SchemaModules>
<SchemaModule Name="SystemModule" Version="24.1.4.0" IsNewNode="True" />
</SchemaModules>
<Views>
<ListView Id="Cargo_Expenses_ListView" DataAccessMode="Server" AllowDelete="True" />
<ListView Id="Cargo_Goods_ListView" DataAccessMode="Server" AllowDelete="False" AllowNew="False" />
<ListView Id="Cargo_ListView" DataAccessMode="Server" />
<ListView Id="Cargo_LookupListView" DataAccessMode="Server" AllowDelete="False" AllowLink="True" AllowNew="False" />
<ListView Id="Carrier_ListView" DataAccessMode="Server" />
<ListView Id="Carrier_LookupListView" DataAccessMode="Server" AllowDelete="False" />
<ListView Id="Client_Goods_ListView" DataAccessMode="Server" AllowDelete="False" AllowLink="False" AllowNew="False" />
<ListView Id="Client_ListView" DataAccessMode="Server" />
<ListView Id="Client_LookupListView" DataAccessMode="Server" AllowDelete="False" AllowNew="False" AllowLink="True" />
<ListView Id="Expense_ListView" DataAccessMode="Server" />
<ListView Id="Expense_LookupListView" DataAccessMode="Server" AllowDelete="False" AllowNew="False" AllowLink="True" />
<ListView Id="Goods_ListView" DataAccessMode="Server" />
<ListView Id="Goods_LookupListView" DataAccessMode="Server" AllowDelete="False" AllowNew="False" AllowLink="True" />
<ListView Id="Goods_Payments_ListView" DataAccessMode="Server" />
<ListView Id="Payment_ListView" DataAccessMode="Server" />
<ListView Id="Payment_LookupListView" AllowDelete="False" AllowNew="False" AllowLink="True" DataAccessMode="Server" />
<ListView Id="Point_ListView" DataAccessMode="Server" />
<ListView Id="Point_LookupListView" DataAccessMode="Server" AllowDelete="False" AllowNew="False" AllowLink="True" />
<ListView Id="Region_ListView" DataAccessMode="Server" />
<ListView Id="Region_LookupListView" AllowDelete="False" />
<ListView Id="Route_ListView" DataAccessMode="Server" />
<ListView Id="Route_LookupListView" DataAccessMode="Server" AllowDelete="False" AllowNew="False" AllowLink="True" />
</Views>
</Application>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<Application />

View File

@ -0,0 +1,14 @@
using Microsoft.AspNetCore.OData.Query.Validator;
using Microsoft.AspNetCore.OData.Query;
namespace DurnyklyYol.Blazor.Server.OData
{
public class MyODataQueryValidator : ODataQueryValidator
{
public override void Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)
{
validationSettings.MaxExpansionDepth = 6;
base.Validate(options, validationSettings);
}
}
}

View File

@ -0,0 +1,57 @@
@page "/"
@namespace DurnyklyYol.Blazor.Server
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@using DevExpress.ExpressApp.Blazor.Components
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<!-- meta name="theme-color" content="#000000" -->
<title>DurnyklyYol</title>
<base href="~/" />
<component type="typeof(BootstrapThemeLink)" render-mode="Static" />
</head>
<body>
@{
string userAgent = Request.Headers["User-Agent"];
bool isIE = userAgent.Contains("MSIE") || userAgent.Contains("Trident");
}
@if(isIE) {
<link href="css/site.css" rel="stylesheet" />
<div class="d-flex flex-column justify-content-center align-items-center h-100">
<div class="d-flex">
<img class="mt-2 mr-4" src="_content/DevExpress.ExpressApp.Blazor/images/Sad.svg" width="60" height="60" />
<div>
<div class="h1">Internet Explorer is not supported.</div>
<p style="font-size: 1rem; opacity: 0.75;" class="m-0">DurnyklyYol cannot be loaded in Internet Explorer.<br>Please use a different browser.</p>
</div>
</div>
</div>
}
else {
<component type="typeof(SplashScreen)" render-mode="Static" param-Caption='"DurnyklyYol"' param-ImagePath='"images/SplashScreen.svg"' />
<link href="_content/DevExpress.ExpressApp.Blazor/styles.css" asp-append-version="true" rel="stylesheet" />
<link href="css/site.css" rel="stylesheet" />
// Uncomment this link to enable CSS isolation. For more information, refer to the following topic: https://learn.microsoft.com/en-us/aspnet/core/blazor/components/css-isolation
//<link href="DurnyklyYol.Blazor.Server.styles.css" rel="stylesheet">
<script src="_content/DevExpress.ExpressApp.Blazor/scripts.js" asp-append-version="true"></script>
<app class="d-none">
<component type="typeof(App)" render-mode="Server" />
</app>
<component type="typeof(AlertsHandler)" render-mode="Server" />
<div id="blazor-error-ui">
<component type="typeof(BlazorError)" render-mode="Static" />
</div>
<script src="_framework/blazor.server.js"></script>
}
</body>
</html>

View File

@ -0,0 +1,52 @@
using System.Reflection;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Blazor.DesignTime;
using DevExpress.ExpressApp.Blazor.Services;
using DevExpress.ExpressApp.Design;
using DevExpress.ExpressApp.Utils;
namespace DurnyklyYol.Blazor.Server;
public class Program : IDesignTimeApplicationFactory {
private static bool ContainsArgument(string[] args, string argument) {
return args.Any(arg => arg.TrimStart('/').TrimStart('-').ToLower() == argument.ToLower());
}
public static int Main(string[] args) {
if(ContainsArgument(args, "help") || ContainsArgument(args, "h")) {
Console.WriteLine("Updates the database when its version does not match the application's version.");
Console.WriteLine();
Console.WriteLine($" {Assembly.GetExecutingAssembly().GetName().Name}.exe --updateDatabase [--forceUpdate --silent]");
Console.WriteLine();
Console.WriteLine("--forceUpdate - Marks that the database must be updated whether its version matches the application's version or not.");
Console.WriteLine("--silent - Marks that database update proceeds automatically and does not require any interaction with the user.");
Console.WriteLine();
Console.WriteLine($"Exit codes: 0 - {DBUpdaterStatus.UpdateCompleted}");
Console.WriteLine($" 1 - {DBUpdaterStatus.UpdateError}");
Console.WriteLine($" 2 - {DBUpdaterStatus.UpdateNotNeeded}");
}
else {
DevExpress.ExpressApp.FrameworkSettings.DefaultSettingsCompatibilityMode = DevExpress.ExpressApp.FrameworkSettingsCompatibilityMode.Latest;
DevExpress.ExpressApp.Security.SecurityStrategy.AutoAssociationReferencePropertyMode = DevExpress.ExpressApp.Security.ReferenceWithoutAssociationPermissionsMode.AllMembers;
IHost host = CreateHostBuilder(args).Build();
if(ContainsArgument(args, "updateDatabase")) {
using(var serviceScope = host.Services.CreateScope()) {
return serviceScope.ServiceProvider.GetRequiredService<DevExpress.ExpressApp.Utils.IDBUpdater>().Update(ContainsArgument(args, "forceUpdate"), ContainsArgument(args, "silent"));
}
}
else {
host.Run();
}
}
return 0;
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => {
webBuilder.UseStartup<Startup>();
//webBuilder.UseUrls("http://0.0.0.0:5555");
});
XafApplication IDesignTimeApplicationFactory.Create() {
IHostBuilder hostBuilder = CreateHostBuilder(Array.Empty<string>());
return DesignTimeApplicationFactoryHelper.Create(hostBuilder);
}
}

View File

@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:65201",
"sslPort": 44318
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"DurnyklyYol.Blazor.Server": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://192.168.99.64:5001;http://192.168.99.64:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,40 @@
Project Description
This project implements an ASP.NET Core Blazor Server application (https://docs.microsoft.com/en-us/aspnet/core/blazor/).
The root project folder contains the BlazorApplication.cs file with the class that inherits
BlazorApplication. This class allows you to view and customize application components: referenced modules,
security settings, data connection. Additionally, the root folder contains
Application Model difference files (XAFML files) that keep settings
specific to the current application. Difference files can be customized in code
or in the Model Editor.
The appsettings.json file contains database connection, logging, and theme settings (https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration).
Relevant Documentation
Application Solution Components
https://docs.devexpress.com/eXpressAppFramework/112569
Debugging, Testing and Error Handling
https://docs.devexpress.com/eXpressAppFramework/112572
XafApplication Class
https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.XafApplication
Application Model (UI Settings Storage)
https://docs.devexpress.com/eXpressAppFramework/112579
Model Editor
https://docs.devexpress.com/eXpressAppFramework/112582
ASP.NET Core Blazor UI
https://docs.devexpress.com/eXpressAppFramework/401675/overview/supported-ui-platforms#aspnet-core-blazor-ui
Frequently Asked Questions - Blazor UI (FAQ)
https://docs.devexpress.com/eXpressAppFramework/403277/support-qa-troubleshooting/frequently-asked-questions-blazor-faq
Backend WebApi Service
https://docs.devexpress.com/eXpressAppFramework/403394/backend-web-api-service
XAF Community Extensions
https://www.devexpress.com/products/net/application_framework/#extensions

View File

@ -0,0 +1,23 @@
using DevExpress.ExpressApp.Blazor.Services;
using Microsoft.AspNetCore.Components.Server.Circuits;
namespace DurnyklyYol.Blazor.Server.Services;
internal class CircuitHandlerProxy : CircuitHandler {
private readonly IScopedCircuitHandler scopedCircuitHandler;
public CircuitHandlerProxy(IScopedCircuitHandler scopedCircuitHandler) {
this.scopedCircuitHandler = scopedCircuitHandler;
}
public override Task OnCircuitOpenedAsync(Circuit circuit, CancellationToken cancellationToken) {
return scopedCircuitHandler.OnCircuitOpenedAsync(cancellationToken);
}
public override Task OnConnectionUpAsync(Circuit circuit, CancellationToken cancellationToken) {
return scopedCircuitHandler.OnConnectionUpAsync(cancellationToken);
}
public override Task OnCircuitClosedAsync(Circuit circuit, CancellationToken cancellationToken) {
return scopedCircuitHandler.OnCircuitClosedAsync(cancellationToken);
}
public override Task OnConnectionDownAsync(Circuit circuit, CancellationToken cancellationToken) {
return scopedCircuitHandler.OnConnectionDownAsync(cancellationToken);
}
}

View File

@ -0,0 +1,27 @@
using DevExpress.ExpressApp.Blazor.Services;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Options;
namespace DurnyklyYol.Blazor.Server.Services;
internal class ProxyHubConnectionHandler<THub> : HubConnectionHandler<THub> where THub : Hub {
private readonly IValueManagerStorageContainerInitializer storageContainerInitializer;
public ProxyHubConnectionHandler(
HubLifetimeManager<THub> lifetimeManager,
IHubProtocolResolver protocolResolver,
IOptions<HubOptions> globalHubOptions,
IOptions<HubOptions<THub>> hubOptions,
ILoggerFactory loggerFactory,
IUserIdProvider userIdProvider,
IServiceScopeFactory serviceScopeFactory,
IValueManagerStorageContainerInitializer storageContainerAccessor)
: base(lifetimeManager, protocolResolver, globalHubOptions, hubOptions, loggerFactory, userIdProvider, serviceScopeFactory) {
this.storageContainerInitializer = storageContainerAccessor;
}
public override Task OnConnectedAsync(ConnectionContext connection) {
storageContainerInitializer.Initialize();
return base.OnConnectedAsync(connection);
}
}

View File

@ -0,0 +1,210 @@
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.ApplicationBuilder;
using DevExpress.ExpressApp.Blazor.ApplicationBuilder;
using DevExpress.ExpressApp.Blazor.Services;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Components.Server.Circuits;
using DurnyklyYol.Blazor.Server.Services;
using DevExpress.Persistent.BaseImpl.PermissionPolicy;
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Microsoft.AspNetCore.OData;
using DevExpress.ExpressApp.WebApi.Services;
using DurnyklyYol.WebApi.JWT;
using DevExpress.ExpressApp.Security.Authentication.ClientServer;
using DurnyklyYol.Blazor.Server.OData;
using Microsoft.AspNetCore.OData.Query.Validator;
namespace DurnyklyYol.Blazor.Server;
public class Startup {
public Startup(IConfiguration configuration) {
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services) {
services.AddSingleton(typeof(Microsoft.AspNetCore.SignalR.HubConnectionHandler<>), typeof(ProxyHubConnectionHandler<>));
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddHttpContextAccessor();
services.AddScoped<IAuthenticationTokenProvider, JwtTokenProviderService>();
services.AddScoped<CircuitHandler, CircuitHandlerProxy>();
services.AddXaf(Configuration, builder => {
builder.UseApplication<DurnyklyYolBlazorApplication>();
builder.AddXafWebApi(webApiBuilder => {
webApiBuilder.AddXpoServices();
webApiBuilder.ConfigureOptions(options => {
// Make your business objects available in the Web API and generate the GET, POST, PUT, and DELETE HTTP methods for it.
// options.BusinessObject<YourBusinessObject>();
options.BusinessObject<Module.BusinessObjects.Contact>();
});
});
builder.Modules
.AddConditionalAppearance()
.AddFileAttachments()
.AddReports(options => {
options.EnableInplaceReports = true;
options.ReportDataType = typeof(DevExpress.Persistent.BaseImpl.ReportDataV2);
options.ReportStoreMode = DevExpress.ExpressApp.ReportsV2.ReportStoreModes.XML;
})
.AddValidation(options => {
options.AllowValidationDetailsAccess = false;
})
.AddViewVariants()
.Add<DurnyklyYol.Module.DurnyklyYolModule>()
.Add<DurnyklyYolBlazorModule>();
builder.ObjectSpaceProviders
.AddSecuredXpo((serviceProvider, options) => {
string connectionString = null;
if(Configuration.GetConnectionString("ConnectionString") != null) {
connectionString = Configuration.GetConnectionString("ConnectionString");
}
#if EASYTEST
if(Configuration.GetConnectionString("EasyTestConnectionString") != null) {
connectionString = Configuration.GetConnectionString("EasyTestConnectionString");
}
#endif
ArgumentNullException.ThrowIfNull(connectionString);
options.ConnectionString = connectionString;
options.ThreadSafe = true;
options.UseSharedDataStoreProvider = true;
})
.AddNonPersistent();
builder.Security
.UseIntegratedMode(options => {
options.Lockout.Enabled = true;
options.RoleType = typeof(PermissionPolicyRole);
// ApplicationUser descends from PermissionPolicyUser and supports the OAuth authentication. For more information, refer to the following topic: https://docs.devexpress.com/eXpressAppFramework/402197
// If your application uses PermissionPolicyUser or a custom user type, set the UserType property as follows:
options.UserType = typeof(DurnyklyYol.Module.BusinessObjects.ApplicationUser);
// ApplicationUserLoginInfo is only necessary for applications that use the ApplicationUser user type.
// If you use PermissionPolicyUser or a custom user type, comment out the following line:
options.UserLoginInfoType = typeof(DurnyklyYol.Module.BusinessObjects.ApplicationUserLoginInfo);
options.UseXpoPermissionsCaching();
options.Events.OnSecurityStrategyCreated += securityStrategy => {
// Use the 'PermissionsReloadMode.NoCache' option to load the most recent permissions from the database once
// for every Session instance when secured data is accessed through this instance for the first time.
// Use the 'PermissionsReloadMode.CacheOnFirstAccess' option to reduce the number of database queries.
// In this case, permission requests are loaded and cached when secured data is accessed for the first time
// and used until the current user logs out.
// See the following article for more details: https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.Security.SecurityStrategy.PermissionsReloadMode.
((SecurityStrategy)securityStrategy).PermissionsReloadMode = PermissionsReloadMode.NoCache;
};
})
.AddPasswordAuthentication(options => {
options.IsSupportChangePassword = true;
});
});
var authentication = services.AddAuthentication(options => {
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
});
authentication.AddCookie(options => {
options.LoginPath = "/LoginPage";
});
authentication.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters() {
ValidateIssuerSigningKey = true,
//ValidIssuer = Configuration["Authentication:Jwt:Issuer"],
//ValidAudience = Configuration["Authentication:Jwt:Audience"],
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authentication:Jwt:IssuerSigningKey"]))
};
});
services.AddAuthorization(options => {
options.DefaultPolicy = new AuthorizationPolicyBuilder(
JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.RequireXafAuthentication()
.Build();
});
services
.AddControllers()
.AddOData((options, serviceProvider) => {
options
.AddRouteComponents("api/odata", new EdmModelBuilder(serviceProvider).GetEdmModel(),
odataServices => {
odataServices.AddSingleton<ODataQueryValidator, MyODataQueryValidator>();
})
.EnableQueryFeatures(100);
});
services.AddSwaggerGen(c => {
c.EnableAnnotations();
c.SwaggerDoc("v1", new OpenApiInfo {
Title = "DurnyklyYol API",
Version = "v1",
Description = @"Use AddXafWebApi(options) in the DurnyklyYol.Blazor.Server\Startup.cs file to make Business Objects available in the Web API."
});
c.AddSecurityDefinition("JWT", new OpenApiSecurityScheme() {
Type = SecuritySchemeType.Http,
Name = "Bearer",
Scheme = "bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement() {
{
new OpenApiSecurityScheme() {
Reference = new OpenApiReference() {
Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme,
Id = "JWT"
}
},
new string[0]
},
});
});
services.Configure<Microsoft.AspNetCore.Mvc.JsonOptions>(o => {
//The code below specifies that the naming of properties in an object serialized to JSON must always exactly match
//the property names within the corresponding CLR type so that the property names are displayed correctly in the Swagger UI.
//XPO is case-sensitive and requires this setting so that the example request data displayed by Swagger is always valid.
//Comment this code out to revert to the default behavior.
//See the following article for more information: https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions.propertynamingpolicy
o.JsonSerializerOptions.PropertyNamingPolicy = null;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
if(env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => {
c.SwaggerEndpoint("/swagger/v1/swagger.json", "DurnyklyYol WebApi v1");
});
}
else {
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. To change this for production scenarios, see: https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRequestLocalization();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseXaf();
app.UseEndpoints(endpoints => {
endpoints.MapXafEndpoints();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
endpoints.MapControllers();
});
}
}

View File

@ -0,0 +1,11 @@
@using System.Net.Http
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using DevExpress.Blazor
@using DevExpress.ExpressApp.Blazor.Components
@using DurnyklyYol.Blazor.Server

View File

@ -0,0 +1,16 @@
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"DevExpress.ExpressApp": "Information"
}
},
"DevExpress": {
"ExpressApp": {
"EnableDiagnosticActions": false
}
}
}

View File

@ -0,0 +1,62 @@
{
"ConnectionStrings": {
"ConnectionString": "XpoProvider=Postgres;server=192.168.99.120;user id=postgres; password=postgres; database=cargo;Encoding=UNICODE",
"ConnectionString2": "Integrated Security=SSPI;Pooling=false;Data Source=(localdb)\\mssqllocaldb;Initial Catalog=DurnyklyYol",
"EasyTestConnectionString": "Integrated Security=SSPI;Pooling=false;Data Source=(localdb)\\mssqllocaldb;Initial Catalog=DurnyklyYolEasyTest"
},
"Authentication": {
"Jwt": {
// For more information, refer to the following topic: Configure the JWT Authentication for the Web API https://docs.devexpress.com/eXpressAppFramework/403504
"Issuer": "My",
"Audience": "http://localhost:4200",
// The debug secret key. You should store sensitive settings in dedicated secret storage. For more information, refer to the following topic: https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-7.0&tabs=windows.
"IssuerSigningKey": "3e3d5a02-f807-493c-a590-4250c04f2c94"
},
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"DevExpress.ExpressApp": "Information"
}
},
"AllowedHosts": "*",
"DevExpress": {
"ExpressApp": {
"Languages": "en-US;tk-TM",
"ShowLanguageSwitcher": true,
"ThemeSwitcher": {
"DefaultItemName": "Office White",
"ShowSizeModeSwitcher": true,
"Groups": [
{
"Caption": "DevExpress Themes",
"Items": [
{
"Caption": "Blazing Berry",
"Url": "_content/DevExpress.Blazor.Themes/blazing-berry.bs5.min.css",
"Color": "#5c2d91"
},
{
"Caption": "Blazing Dark",
"Url": "_content/DevExpress.Blazor.Themes/blazing-dark.bs5.min.css",
"Color": "#46444a"
},
{
"Caption": "Office White",
"Url": "_content/DevExpress.Blazor.Themes/office-white.bs5.min.css",
"Color": "#fe7109"
},
{
"Caption": "Purple",
"Url": "_content/DevExpress.Blazor.Themes/purple.bs5.min.css",
"Color": "#7989ff"
}
]
}
]
}
}
}
}

View File

@ -0,0 +1,31 @@
html, body {
height: 100%;
}
app {
display: block;
height: 100%;
}
.header-logo {
flex-shrink: 0;
background-color: currentColor;
-webkit-mask: url('../images/Logo.svg');
mask: url('../images/Logo.svg');
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
width: 180px;
height: 24px;
}
#blazor-error-ui {
background: inherit;
bottom: 0;
display: none;
position: fixed;
width: 100%;
height: 100%;
z-index: 100001;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 28.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 180 24" style="enable-background:new 0 0 180 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#4A4A4A;}
</style>
<g>
<path class="st0" d="M17.2,19.3h-4.8V5.7h4.9c1.4,0,2.5,0.3,3.5,0.8c1,0.5,1.7,1.3,2.3,2.3c0.5,1,0.8,2.2,0.8,3.6
c0,1.4-0.3,2.6-0.8,3.7c-0.5,1-1.3,1.8-2.3,2.3C19.8,19.1,18.6,19.3,17.2,19.3z M15.3,16.9h1.8c0.9,0,1.6-0.2,2.1-0.5
c0.6-0.3,1-0.8,1.3-1.4c0.3-0.6,0.4-1.5,0.4-2.5c0-1-0.1-1.8-0.4-2.5c-0.3-0.6-0.7-1.1-1.3-1.4c-0.6-0.3-1.3-0.5-2.1-0.5h-1.8V16.9
z"/>
<path class="st0" d="M32.1,15V9.1H35v10.2h-2.7v-1.9h-0.1c-0.2,0.6-0.6,1.1-1.1,1.4c-0.5,0.4-1.2,0.5-1.9,0.5
c-0.7,0-1.3-0.2-1.8-0.5c-0.5-0.3-0.9-0.8-1.2-1.3s-0.4-1.3-0.4-2.1V9.1h2.8v6c0,0.6,0.2,1.1,0.5,1.4c0.3,0.3,0.7,0.5,1.3,0.5
c0.3,0,0.7-0.1,1-0.2s0.5-0.4,0.7-0.7C32,15.8,32.1,15.4,32.1,15z"/>
<path class="st0" d="M36.8,19.3V9.1h2.7v1.8h0.1c0.2-0.6,0.5-1.1,0.9-1.4C41.1,9.2,41.6,9,42.1,9c0.1,0,0.3,0,0.5,0
c0.2,0,0.3,0,0.4,0.1v2.5c-0.1,0-0.3-0.1-0.6-0.1c-0.2,0-0.4,0-0.6,0c-0.4,0-0.8,0.1-1.1,0.3s-0.6,0.4-0.8,0.7
c-0.2,0.3-0.3,0.7-0.3,1.1v5.8H36.8z"/>
<path class="st0" d="M46.9,13.4v5.9h-2.8V9.1h2.7v1.8h0.1c0.2-0.6,0.6-1.1,1.1-1.4C48.6,9.2,49.2,9,50,9c0.7,0,1.3,0.2,1.9,0.5
c0.5,0.3,0.9,0.8,1.2,1.3c0.3,0.6,0.4,1.3,0.4,2v6.5h-2.8v-6c0-0.6-0.2-1.1-0.5-1.5c-0.3-0.4-0.8-0.5-1.3-0.5c-0.4,0-0.7,0.1-1,0.2
c-0.3,0.2-0.5,0.4-0.7,0.7C47,12.6,46.9,13,46.9,13.4z"/>
<path class="st0" d="M61.9,15V9.1h2.8v10.2H62v-1.9h-0.1c-0.2,0.6-0.6,1.1-1.1,1.4c-0.5,0.4-1.2,0.5-1.9,0.5
c-0.7,0-1.3-0.2-1.8-0.5c-0.5-0.3-0.9-0.8-1.2-1.3s-0.4-1.3-0.4-2.1V9.1h2.8v6c0,0.6,0.2,1.1,0.5,1.4c0.3,0.3,0.7,0.5,1.3,0.5
c0.3,0,0.7-0.1,1-0.2s0.5-0.4,0.7-0.7C61.8,15.8,61.9,15.4,61.9,15z"/>
<path class="st0" d="M66.6,19.3V5.7h2.8v13.6H66.6z M69.2,16.4l0-3.4h0.4l3.3-3.9h3.2l-4.4,5.1h-0.7L69.2,16.4z M73,19.3l-3-4.4
l1.9-2l4.4,6.4H73z"/>
<path class="st0" d="M79.9,5.7v13.6h-2.8V5.7H79.9z"/>
<path class="st0" d="M83.6,23.2c-0.4,0-0.7,0-1-0.1c-0.3-0.1-0.6-0.1-0.8-0.2l0.6-2.1c0.3,0.1,0.6,0.2,0.9,0.2
c0.3,0,0.5-0.1,0.7-0.2c0.2-0.1,0.4-0.4,0.5-0.7l0.2-0.4L81,9.1h3l2.1,7.5h0.1l2.1-7.5h3l-4,11.3c-0.2,0.5-0.4,1-0.8,1.4
c-0.3,0.4-0.7,0.7-1.2,0.9C84.9,23,84.3,23.2,83.6,23.2z"/>
<path class="st0" d="M95.6,5.7h3.2l3.1,5.9h0.1l3.1-5.9h3.2l-5,8.8v4.8h-2.9v-4.8L95.6,5.7z M101,4.4l1.4-3h2.6l-2,3H101z"/>
<path class="st0" d="M112,19.5c-1,0-1.9-0.2-2.7-0.7c-0.8-0.4-1.3-1.1-1.7-1.8s-0.6-1.7-0.6-2.8c0-1.1,0.2-2,0.6-2.8s1-1.4,1.7-1.8
S111,9,112,9c1,0,1.9,0.2,2.7,0.7c0.8,0.4,1.3,1.1,1.7,1.8s0.6,1.7,0.6,2.8c0,1-0.2,2-0.6,2.8s-1,1.4-1.7,1.8
C114,19.3,113.1,19.5,112,19.5z M112,17.3c0.5,0,0.9-0.1,1.2-0.4c0.3-0.3,0.6-0.6,0.7-1.1c0.2-0.5,0.2-1,0.2-1.6
c0-0.6-0.1-1.1-0.2-1.6c-0.2-0.5-0.4-0.8-0.7-1.1c-0.3-0.3-0.7-0.4-1.2-0.4c-0.5,0-0.9,0.1-1.2,0.4c-0.3,0.3-0.6,0.6-0.7,1.1
c-0.2,0.5-0.2,1-0.2,1.6c0,0.6,0.1,1.1,0.2,1.6c0.2,0.5,0.4,0.8,0.7,1.1C111.2,17.2,111.6,17.3,112,17.3z"/>
<path class="st0" d="M121.4,5.7v13.6h-2.8V5.7H121.4z"/>
<path class="st0" d="M139.3,10.5h-2.9c-0.1-0.4-0.2-0.7-0.3-1c-0.2-0.3-0.4-0.5-0.6-0.8s-0.6-0.4-0.9-0.5c-0.3-0.1-0.7-0.2-1.1-0.2
c-0.7,0-1.3,0.2-1.8,0.5c-0.5,0.3-0.9,0.9-1.2,1.5c-0.3,0.7-0.4,1.5-0.4,2.4c0,1,0.1,1.8,0.4,2.4c0.3,0.7,0.7,1.2,1.2,1.5
c0.5,0.3,1.1,0.5,1.8,0.5c0.4,0,0.7-0.1,1.1-0.2c0.3-0.1,0.6-0.3,0.9-0.4c0.3-0.2,0.5-0.4,0.6-0.7c0.2-0.3,0.3-0.6,0.4-1l2.9,0
c-0.1,0.6-0.3,1.2-0.6,1.8c-0.3,0.6-0.7,1.1-1.2,1.5c-0.5,0.5-1.1,0.8-1.8,1.1c-0.7,0.3-1.5,0.4-2.3,0.4c-1.2,0-2.3-0.3-3.2-0.8
s-1.7-1.3-2.3-2.4c-0.6-1-0.8-2.3-0.8-3.8c0-1.5,0.3-2.7,0.8-3.8s1.3-1.8,2.3-2.4c1-0.5,2-0.8,3.2-0.8c0.8,0,1.5,0.1,2.2,0.3
c0.7,0.2,1.3,0.5,1.8,1s0.9,0.9,1.3,1.6S139.2,9.7,139.3,10.5z"/>
<path class="st0" d="M140.9,19.3V5.7h5.4c1,0,1.9,0.2,2.6,0.5s1.3,0.9,1.7,1.5c0.4,0.7,0.6,1.4,0.6,2.3c0,0.9-0.2,1.7-0.6,2.3
c-0.4,0.6-1,1.1-1.7,1.5c-0.7,0.3-1.6,0.5-2.7,0.5h-3.6v-2.3h3.1c0.5,0,1-0.1,1.4-0.2s0.6-0.4,0.8-0.7c0.2-0.3,0.3-0.7,0.3-1.1
c0-0.5-0.1-0.8-0.3-1.1c-0.2-0.3-0.5-0.5-0.8-0.7c-0.4-0.2-0.8-0.2-1.4-0.2h-1.9v11.2H140.9z M148.3,13.1l3.4,6.2h-3.2l-3.3-6.2
H148.3z"/>
<path class="st0" d="M152.8,5.7h3.5l3.7,9.1h0.2l3.7-9.1h3.5v13.6h-2.8v-8.9h-0.1l-3.5,8.8h-1.9l-3.5-8.8h-0.1v8.9h-2.8V5.7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,41 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 180 24" style="enable-background:new 0 0 180 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#4A4A4A;}
</style>
<path class="st0" d="M3.9,8.1c-3.5-0.1-4.3,4.4-3.8,7c0.3,1.5,1,3,2.5,3.6c1.4,0.6,3.3,0.4,4.6-0.4v-2.1C6.3,16.9,5,17.3,4,17
c-1.1-0.4-1.4-1.7-1.4-2.7h5.1C7.7,11.7,7.4,8,3.9,8.1z M2.6,12.5c0-0.8,0.3-2.3,1.3-2.4c1.1,0,1.3,1.6,1.3,2.4H2.6z M14.3,11.9
l3.2,7.1h-2.7l-2-5l-1.8,5H8.3l3.2-7.2L8.5,5h2.6l1.8,4.6L14.5,5h2.8L14.3,11.9z M23.3,8.2c-1,0-1.9,0.6-2.3,1.5h-0.1l-0.4-1.4h-2
v15.3h2.5c0-1.9,0.2-4-0.2-5.9h0.1c0.6,1.2,2,1.7,3.3,1.2c1.3-0.6,1.8-2.3,2-3.7C26.7,13,26.5,8.1,23.3,8.2L23.3,8.2z M22.5,17
c-1.6,0-1.4-2.6-1.4-3.6c0-1,0.1-3.7,1.8-3c1.3,0.6,1,3.3,0.9,4.5C23.7,15.6,23.5,16.9,22.5,17L22.5,17z M32.7,8.2
c0.3,0,0.6,0,0.9,0.1l-0.3,2.4c-2.6-0.7-2.6,2.3-2.6,4.1c0,1.4,0,2.8,0,4.2h-2.6V8.3h2.1l0.3,1.7l0,0C30.9,9.1,31.7,8.1,32.7,8.2
L32.7,8.2z M38.3,8.2c-3.5-0.1-4.3,4.4-3.8,7c0.3,1.5,1,3,2.5,3.6c1.4,0.6,3.3,0.4,4.7-0.4v-2.1c-0.9,0.5-2.2,1-3.2,0.6
c-1-0.4-1.4-1.7-1.4-2.7h5.1c0-1.1,0.1-2.2-0.2-3.2C41.4,9.4,40.2,8,38.3,8.2L38.3,8.2z M37,12.5c0-0.8,0.2-2.2,1.2-2.3
c1.2-0.2,1.4,1.5,1.4,2.3H37z M49.2,14.6c0.6,1.4,0.2,3.3-1.2,4c-1.4,0.8-3.4,0.6-4.7-0.1v-2.2c0.8,0.6,4.2,1.7,3.6-0.5
c-0.2-0.8-1.1-1.2-1.7-1.6c-0.6-0.4-1.2-0.9-1.5-1.5c-0.7-1.4-0.3-3.3,1.1-4.1c1.4-0.8,3.3-0.5,4.7,0.3l-0.8,1.8
c-0.5-0.3-1.4-0.7-2-0.5c-0.7,0.2-0.9,0.9-0.6,1.4c0.4,0.7,1.3,1,1.9,1.4C48.4,13.4,48.9,13.9,49.2,14.6L49.2,14.6z M56.5,14.6
c0.5,1.4,0.2,3.2-1.2,4c-1.4,0.8-3.4,0.6-4.7-0.1v-2.2c0.8,0.6,4.2,1.7,3.6-0.5c-0.2-0.8-1.1-1.2-1.7-1.6c-0.6-0.4-1.2-0.9-1.5-1.5
c-0.8-1.4-0.3-3.3,1.1-4.1c1.4-0.8,3.3-0.5,4.7,0.3l-0.8,1.8c-0.5-0.3-1.4-0.7-2.1-0.5c-0.6,0.2-0.9,0.8-0.6,1.4
c0.3,0.7,1.3,1,1.9,1.4C55.7,13.4,56.2,13.9,56.5,14.6L56.5,14.6z M60.6,5l-3.4,13.9h2.6l0.8-3.5h3.6l0.8,3.5h2.6L64.2,5L60.6,5z
M61.1,13.2c0.5-2.1,1-4.2,1.3-6.3c0,1.1,0.4,2.4,0.7,3.5c0.2,0.9,0.4,1.9,0.6,2.8H61.1z M73.5,8.2c-1,0-1.9,0.6-2.3,1.5h-0.1
l-0.4-1.4h-2v15.3h2.5c0-1.9,0.2-4-0.1-5.9h0.1c0.7,1.3,2.3,1.8,3.5,1c1.2-0.7,1.6-2.4,1.8-3.7C76.8,12.9,76.6,8.2,73.5,8.2
L73.5,8.2z M72.6,17c-1.6,0-1.4-2.6-1.4-3.6c0-1,0.1-3.8,1.9-3c1.3,0.6,1,3.4,0.8,4.5C73.9,15.6,73.6,16.9,72.6,17L72.6,17z
M83.1,8.2c-1,0-1.9,0.6-2.3,1.5h-0.1l-0.4-1.4h-2v15.3h2.5c0-1.9,0.2-4-0.2-5.9h0.1c0.6,1.2,2,1.7,3.3,1.2c1.3-0.6,1.8-2.3,2-3.7
C86.5,13,86.3,8.1,83.1,8.2L83.1,8.2z M82.3,17c-1.6,0-1.4-2.6-1.4-3.6c0-0.9,0.1-3.6,1.8-3c1.4,0.5,1.1,3.4,1,4.5
C83.5,15.6,83.3,16.9,82.3,17L82.3,17z M93,5h6.2v2.2h-3.7v3.8h3.4v2.3h-3.4v5.6H93V5z M105.3,8.1c0.3,0,0.6,0,0.9,0.1l-0.3,2.4
c-2.6-0.7-2.6,2.3-2.6,4.1c0,1.4,0,2.8,0,4.2h-2.6V8.3h2.1l0.3,1.7h0.1C103.6,9.1,104.3,8.2,105.3,8.1z M111,8.1
c-1.2,0-2.4,0.3-3.4,1l0.9,1.8c0.7-0.5,2.3-1.2,3.1-0.4c0.5,0.5,0.4,1.3,0.4,1.9c-2.2,0-4.8,0.2-5.1,2.9c-0.1,1.3,0.2,3.1,1.6,3.6
c1.4,0.6,2.9-0.2,3.6-1.5l0,0l0.5,1.4h1.8c0-1.7,0-3.5,0-5.2c0-0.6,0-1.2,0-1.8C114.3,9.8,113.2,8,111,8.1L111,8.1z M111.9,14.9
c0,0.8-0.3,1.9-1.1,2.2c-0.7,0.2-1.2-0.2-1.3-0.8c-0.3-1.8,0.9-2.3,2.4-2.3V14.9z M128.8,9.1c1,1.6,0.7,3.7,0.7,5.5
c0,1.5,0,2.9,0,4.4h-2.6c0-1.4,0-2.8,0-4.2c0-1.1,0.3-3.5-0.5-4.3c-1.3-1.1-2,1-2.1,1.9c-0.1,0.7-0.1,1.5-0.1,2.2c0,1.4,0,2.9,0,4.3
h-2.6c0-1.4,0-2.8,0-4.1c0-1.1,0.3-3.5-0.5-4.3c-1.3-1.1-2,1.1-2.1,2c-0.1,0.7,0,1.5,0,2.2c0,1.4,0,2.8,0,4.3h-2.5V8.3h2l0.3,1.4
h0.2c0.9-2.2,4.4-2,5,0.3h0.1C124.7,8.1,127.5,7.4,128.8,9.1z M135.1,8.1c-3.5-0.1-4.3,4.4-3.8,7c0.3,1.5,1,3,2.5,3.6
c1.4,0.6,3.3,0.4,4.7-0.4v-2.1c-0.9,0.6-2.2,1-3.2,0.7c-1.1-0.4-1.4-1.7-1.4-2.7h5.1c0-1,0.1-2.1-0.2-3.1C138.2,9.5,137,8,135.1,8.1
z M133.8,12.5c0-0.8,0.3-2.3,1.3-2.4c1.1,0,1.3,1.6,1.2,2.4H133.8z M150.8,8.3h2.5l-2.1,10.6h-3.3c-0.5-2.9-1-5.8-1.4-8.7l0,0
c-0.3,2.9-0.9,5.9-1.4,8.8h-3.3l-2.1-10.6h2.5c0.5,2.9,1.1,5.7,1.3,8.6l0,0c0-2.9,0.9-5.8,1.4-8.6h3.3c0.5,2.8,1.2,5.7,1.3,8.6l0,0
C149.6,14,150.3,11.2,150.8,8.3z M158.3,8.1c-5.7-0.3-5.6,11,0.1,10.9c2.8,0,4-2.8,4-5.3C162.4,11.3,161.4,8,158.3,8.1L158.3,8.1z
M158.3,16.9c-1.7,0-1.6-3-1.5-4.1c0.1-1.1,0.6-3.4,2.2-2.4c1.2,0.8,1,3.2,0.8,4.4C159.7,15.7,159.4,17,158.3,16.9L158.3,16.9z
M168.7,8.1c0.3,0,0.7,0.1,1,0.2l-0.3,2.4c-2.6-0.7-2.6,2.3-2.6,4.1c0,1.4,0,2.8,0,4.2h-2.7V8.3h2.1l0.3,1.7h0.1
C166.9,9.1,167.6,8.1,168.7,8.1L168.7,8.1z M178.8,18.9h-2.7l-1.9-4.5l-1,0.9v3.6h-2.5V4.1h2.5c0,3,0,6.1-0.1,9.1l0,0
c0.8-1.7,1.8-3.3,2.8-4.9h2.7l-2.7,4.4L178.8,18.9z"/>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 28.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="_x31_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 46 30" style="enable-background:new 0 0 46 30;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M12.7,20.6v1.1c0,3.2-0.5,7.7-6.5,7.7c-5.2,0-6.3-3.2-6.3-7.5V7.8c0-4.3,2-7.2,6.4-7.2c5.2,0,6.3,3.5,6.3,7.4
v1.3H8.3V7.4c0-1.9-0.4-2.9-1.9-2.9c-1.5,0-2,1-2,2.9v14.8c0,1.8,0.4,3.2,2,3.2c1.6,0,2-1.2,2-3.3v-1.6H12.7z"/>
<path class="st0" d="M18.1,16.5V29h-4.3V1h6c4.3,0,6.8,1.7,6.8,6.7v1.1c0,4.3-1.8,5.4-2.8,5.8c1.6,0.8,2.6,1.9,2.6,5.7
c0,2.4,0,6.9,0.3,8.6h-4.2c-0.4-1.7-0.3-6.3-0.3-8.3c0-3.4-0.4-4.2-2.9-4.2H18.1z M18.1,12.9h1c2.3,0,3.1-0.9,3.1-3.9v-1
c0-2.2-0.4-3.5-2.9-3.5h-1.2V12.9z"/>
<path class="st0" d="M41.9,18.6c0-4.8,0.1-10.7,0.1-13.9h0c-0.6,4.9-2.2,16.2-3.4,24.3h-4.1C33.6,21.7,32,9.8,31.4,4.7h-0.1
c0.1,3.3,0.2,9.6,0.2,14.4V29h-3.9V1h6.4c1.1,7.1,2.2,15.1,2.6,19h0c0.5-4,2-12.3,3.1-19H46v28h-4.1V18.6z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,11 @@
<svg version="1.1" id="_x31_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 46 30" style="enable-background:new 0 0 46 30;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path id="_x33_" class="st0" d="M25.8,0h-3.2l-6.7,29.9l-5.7-15.2L15.9,0h-4.2l-2,6.2L9.4,7.1C9.2,7.7,9,8.3,8.8,8.9
c-0.2,0.6-0.3,1.3-0.5,1.9c-0.2-1.1-0.7-2.7-1.5-5L4.7,0h-4l5.5,14.8L0.3,30h4.4l1.8-5.4l0.4-1.1l0.7-2.1c0.3-0.8,0.4-1.6,0.5-2.5
c0.1,0.7,0.3,1.5,0.5,2.4c0.3,0.9,0.6,1.9,1,3.1l2,5.7h4.2h0h4l1.2-5.8h6.1l1.2,5.8h4.1L25.8,0z M21.6,21l0.8-3.8
c0.4-2.1,0.7-4,1-5.9c0.3-1.8,0.5-3.7,0.7-5.5c0.4,3.7,0.9,7.2,1.5,10.4l0.9,4.8H21.6z"/>
<polygon id="_x32_" class="st0" points="46,0 35,0 35,30 39.1,30 39.1,16.3 45.3,16.3 45.3,12.9 39.1,12.9 39.1,3.4 46,3.4 "/>
</svg>

After

Width:  |  Height:  |  Size: 834 B

View File

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<Deterministic>false</Deterministic>
<AssemblyVersion>1.0.*</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<Configurations>Debug;Release;EasyTest</Configurations>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DevExpress.Drawing.Skia" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Api.Xpo.All" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.CodeAnalysis" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Security.AspNetCore.Xpo" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Security.Xpo" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Xpo" Version="24.1.4" />
<PackageReference Include="DevExpress.Persistent.Base" Version="24.1.4" />
<PackageReference Include="DevExpress.Persistent.BaseImpl.Xpo" Version="24.1.4" />
<PackageReference Include="DevExpress.RichEdit.Export" Version="24.1.4" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DurnyklyYol.Module\DurnyklyYol.Module.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,37 @@
using System.IdentityModel.Tokens.Jwt;
using System.Runtime.ExceptionServices;
using System.Security.Claims;
using System.Text;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.Security.Authentication.ClientServer;
using Microsoft.IdentityModel.Tokens;
namespace DurnyklyYol.WebApi.JWT;
public class JwtTokenProviderService : IAuthenticationTokenProvider {
readonly SignInManager signInManager;
readonly IConfiguration configuration;
public JwtTokenProviderService(SignInManager signInManager, IConfiguration configuration) {
this.signInManager = signInManager;
this.configuration = configuration;
}
public string Authenticate(object logonParameters) {
var result = signInManager.AuthenticateByLogonParameters(logonParameters);
if(result.Succeeded) {
var issuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Authentication:Jwt:IssuerSigningKey"]));
var token = new JwtSecurityToken(
//issuer: configuration["Authentication:Jwt:Issuer"],
//audience: configuration["Authentication:Jwt:Audience"],
claims: result.Principal.Claims,
expires: DateTime.Now.AddDays(2),
signingCredentials: new SigningCredentials(issuerSigningKey, SecurityAlgorithms.HmacSha256)
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
if(result.Error is IUserFriendlyException) {
ExceptionDispatchInfo.Throw(result.Error);
}
throw new AuthenticationException("Internal server error");
}
}

View File

@ -0,0 +1,29 @@
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.Security.Authentication;
using DevExpress.ExpressApp.Security.Authentication.ClientServer;
using Microsoft.AspNetCore.Mvc;
namespace DurnyklyYol.WebApi.JWT;
[ApiController]
[Route("api/[controller]")]
// This is a JWT authentication service sample.
public class AuthenticationController : ControllerBase {
readonly IAuthenticationTokenProvider tokenProvider;
public AuthenticationController(IAuthenticationTokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
}
[HttpPost("Authenticate")]
public IActionResult Authenticate(
[FromBody]
AuthenticationStandardLogonParameters logonParameters
) {
try {
return Ok(tokenProvider.Authenticate(logonParameters));
}
catch(AuthenticationException ex) {
return Unauthorized(ex.GetJson());
}
}
}

View File

@ -0,0 +1,50 @@
using System.Reflection;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.AspNetCore.DesignTime;
using DevExpress.ExpressApp.Design;
using DevExpress.ExpressApp.Utils;
namespace DurnyklyYol.WebApi;
public class Program : IDesignTimeApplicationFactory {
private static bool ContainsArgument(string[] args, string argument) {
return args.Any(arg => arg.TrimStart('/').TrimStart('-').ToLower() == argument.ToLower());
}
public static int Main(string[] args) {
if(ContainsArgument(args, "help") || ContainsArgument(args, "h")) {
Console.WriteLine("Updates the database when its version does not match the application's version.");
Console.WriteLine();
Console.WriteLine($" {Assembly.GetExecutingAssembly().GetName().Name}.exe --updateDatabase [--forceUpdate --silent]");
Console.WriteLine();
Console.WriteLine("--forceUpdate - Marks that the database must be updated whether its version matches the application's version or not.");
Console.WriteLine("--silent - Marks that database update proceeds automatically and does not require any interaction with the user.");
Console.WriteLine();
Console.WriteLine($"Exit codes: 0 - {DBUpdaterStatus.UpdateCompleted}");
Console.WriteLine($" 1 - {DBUpdaterStatus.UpdateError}");
Console.WriteLine($" 2 - {DBUpdaterStatus.UpdateNotNeeded}");
}
else {
DevExpress.ExpressApp.FrameworkSettings.DefaultSettingsCompatibilityMode = DevExpress.ExpressApp.FrameworkSettingsCompatibilityMode.Latest;
DevExpress.ExpressApp.Security.SecurityStrategy.AutoAssociationReferencePropertyMode = DevExpress.ExpressApp.Security.ReferenceWithoutAssociationPermissionsMode.AllMembers;
IHost host = CreateHostBuilder(args).Build();
if(ContainsArgument(args, "updateDatabase")) {
using(var serviceScope = host.Services.CreateScope()) {
return serviceScope.ServiceProvider.GetRequiredService<DevExpress.ExpressApp.Utils.IDBUpdater>().Update(ContainsArgument(args, "forceUpdate"), ContainsArgument(args, "silent"));
}
}
else {
host.Run();
}
}
return 0;
}
XafApplication IDesignTimeApplicationFactory.Create() {
IHostBuilder hostBuilder = CreateHostBuilder(Array.Empty<string>());
return DesignTimeApplicationFactoryHelper.Create(hostBuilder);
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => {
webBuilder.UseStartup<Startup>();
});
}

View File

@ -0,0 +1,30 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:5000",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "MiddleTier/Index",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"DurnyklyYol.MiddleTier": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchUrl": "MiddleTier/Index",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,15 @@
Project Description
This project implements an ASP.NET Core Web API application (https://docs.devexpress.com/eXpressAppFramework/403394/backend-web-api-service).
The appsettings.json file contains database connection, logging, and authentication settings (https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration).
YOUR FEEDBACK MATTERS
Please tell us how our Web API Service works for you: https://www.devexpress.com/go/XAF_WebAPI_Feedback.aspx - THANKS!
Relevant Documentation
Backend Web API Service
https://docs.devexpress.com/eXpressAppFramework/403394/backend-web-api-service
Overview
https://www.devexpress.com/products/net/application_framework/security-web-api-service.xml

View File

@ -0,0 +1,125 @@
using DevExpress.ExpressApp.Security;
using DevExpress.Persistent.Base;
using DevExpress.ExpressApp.Xpo;
using DevExpress.Persistent.BaseImpl.PermissionPolicy;
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using DurnyklyYol.WebApi.JWT;
using DevExpress.ExpressApp.Security.Authentication.ClientServer;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.ApplicationBuilder;
namespace DurnyklyYol.WebApi;
public class Startup {
public Startup(IConfiguration configuration) {
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services) {
services.AddScoped<IAuthenticationTokenProvider, JwtTokenProviderService>();
services.AddXafMiddleTier(Configuration, builder => {
builder.ConfigureDataServer(options => {
options.UseConnectionString(Configuration.GetConnectionString("ConnectionString"));
options.UseDataStorePool(true);
});
builder.Modules
.AddReports(options => {
options.ReportDataType = typeof(DevExpress.Persistent.BaseImpl.ReportDataV2);
})
.Add<DurnyklyYol.Module.DurnyklyYolModule>();
builder.Security
.UseIntegratedMode(options => {
options.Lockout.Enabled = true;
options.RoleType = typeof(PermissionPolicyRole);
// ApplicationUser descends from PermissionPolicyUser and supports the OAuth authentication. For more information, refer to the following topic: https://docs.devexpress.com/eXpressAppFramework/402197
// If your application uses PermissionPolicyUser or a custom user type, set the UserType property as follows:
options.UserType = typeof(DurnyklyYol.Module.BusinessObjects.ApplicationUser);
// ApplicationUserLoginInfo is only necessary for applications that use the ApplicationUser user type.
// If you use PermissionPolicyUser or a custom user type, comment out the following line:
options.UserLoginInfoType = typeof(DurnyklyYol.Module.BusinessObjects.ApplicationUserLoginInfo);
options.UseXpoPermissionsCaching();
options.Events.OnSecurityStrategyCreated += securityStrategy => {
//((SecurityStrategy)securityStrategy).AnonymousAllowedTypes.Add(typeof(DevExpress.Persistent.BaseImpl.ModelDifference));
//((SecurityStrategy)securityStrategy).AnonymousAllowedTypes.Add(typeof(DevExpress.Persistent.BaseImpl.ModelDifferenceAspect));
((SecurityStrategy)securityStrategy).PermissionsReloadMode = PermissionsReloadMode.CacheOnFirstAccess;
};
})
.AddPasswordAuthentication(options => {
options.IsSupportChangePassword = true;
});
builder.AddBuildStep(application => {
application.ApplicationName = "SetupApplication.DurnyklyYol";
application.CheckCompatibilityType = DevExpress.ExpressApp.CheckCompatibilityType.DatabaseSchema;
//application.CreateCustomModelDifferenceStore += += (s, e) => {
// e.Store = new ModelDifferenceDbStore((XafApplication)sender!, typeof(ModelDifference), true, "Win");
// e.Handled = true;
//};
#if !RELEASE
if(application.CheckCompatibilityType == CheckCompatibilityType.DatabaseSchema) {
application.DatabaseUpdateMode = DatabaseUpdateMode.UpdateDatabaseAlways;
application.DatabaseVersionMismatch += (s, e) => {
e.Updater.Update();
e.Handled = true;
};
}
#endif
});
});
services.AddAuthentication()
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters() {
ValidateIssuerSigningKey = true,
//ValidIssuer = Configuration["Authentication:Jwt:Issuer"],
//ValidAudience = Configuration["Authentication:Jwt:Audience"],
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authentication:Jwt:IssuerSigningKey"]))
};
});
services.AddAuthorization(options => {
options.DefaultPolicy = new AuthorizationPolicyBuilder(
JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.RequireXafAuthentication()
.Build();
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime hostApplicationLifetime) {
if(env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
else {
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. To change this for production scenarios, see: https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRequestLocalization();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseXafMiddleTier();
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
});
}
}

View File

@ -0,0 +1,16 @@
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"DevExpress.ExpressApp": "Information"
}
},
"DevExpress": {
"ExpressApp": {
"EnableDiagnosticActions": false
}
}
}

View File

@ -0,0 +1,29 @@
{
"ConnectionStrings": {
"ConnectionString": "Integrated Security=SSPI;Pooling=false;Data Source=(localdb)\\mssqllocaldb;Initial Catalog=DurnyklyYol",
"EasyTestConnectionString": "Integrated Security=SSPI;Pooling=false;Data Source=(localdb)\\mssqllocaldb;Initial Catalog=DurnyklyYolEasyTest"
},
"Authentication": {
"Jwt": {
// For more information, refer to the following topic: Configure the JWT Authentication for the Web API https://docs.devexpress.com/eXpressAppFramework/403504
"Issuer": "My",
"Audience": "http://localhost:4200",
// The debug secret key. You should store sensitive settings in dedicated secret storage. For more information, refer to the following topic: https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-7.0&tabs=windows.
"IssuerSigningKey": "3e3d5a02-f807-493c-a590-4250c04f2c94"
},
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"DevExpress.ExpressApp": "Information"
}
},
"AllowedHosts": "*",
"DevExpress": {
"ExpressApp": {
"Languages": "en-US;"
}
}
}

View File

@ -0,0 +1,45 @@
using System.ComponentModel;
using System.Text;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Security;
using DevExpress.Persistent.BaseImpl.PermissionPolicy;
using DevExpress.Xpo;
namespace DurnyklyYol.Module.BusinessObjects;
[MapInheritance(MapInheritanceType.ParentTable)]
[DefaultProperty(nameof(UserName))]
public class ApplicationUser : PermissionPolicyUser, ISecurityUserWithLoginInfo, ISecurityUserLockout {
private int accessFailedCount;
private DateTime lockoutEnd;
public ApplicationUser(Session session) : base(session) { }
[Browsable(false)]
public int AccessFailedCount {
get { return accessFailedCount; }
set { SetPropertyValue(nameof(AccessFailedCount), ref accessFailedCount, value); }
}
[Browsable(false)]
public DateTime LockoutEnd {
get { return lockoutEnd; }
set { SetPropertyValue(nameof(LockoutEnd), ref lockoutEnd, value); }
}
[Browsable(false)]
[Aggregated, Association("User-LoginInfo")]
public XPCollection<ApplicationUserLoginInfo> LoginInfo {
get { return GetCollection<ApplicationUserLoginInfo>(nameof(LoginInfo)); }
}
IEnumerable<ISecurityUserLoginInfo> IOAuthSecurityUser.UserLogins => LoginInfo.OfType<ISecurityUserLoginInfo>();
ISecurityUserLoginInfo ISecurityUserWithLoginInfo.CreateUserLoginInfo(string loginProviderName, string providerUserKey) {
ApplicationUserLoginInfo result = new ApplicationUserLoginInfo(Session);
result.LoginProviderName = loginProviderName;
result.ProviderUserKey = providerUserKey;
result.User = this;
return result;
}
}

View File

@ -0,0 +1,36 @@
using DevExpress.ExpressApp.ConditionalAppearance;
using DevExpress.ExpressApp.Security;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Xpo;
namespace DurnyklyYol.Module.BusinessObjects;
[DeferredDeletion(false)]
[Persistent("PermissionPolicyUserLoginInfo")]
public class ApplicationUserLoginInfo : BaseObject, ISecurityUserLoginInfo {
private string loginProviderName;
private ApplicationUser user;
private string providerUserKey;
public ApplicationUserLoginInfo(Session session) : base(session) { }
[Indexed("ProviderUserKey", Unique = true)]
[Appearance("PasswordProvider", Enabled = false, Criteria = "!(IsNewObject(this)) and LoginProviderName == '" + SecurityDefaults.PasswordAuthentication + "'", Context = "DetailView")]
public string LoginProviderName {
get { return loginProviderName; }
set { SetPropertyValue(nameof(LoginProviderName), ref loginProviderName, value); }
}
[Appearance("PasswordProviderUserKey", Enabled = false, Criteria = "!(IsNewObject(this)) and LoginProviderName == '" + SecurityDefaults.PasswordAuthentication + "'", Context = "DetailView")]
public string ProviderUserKey {
get { return providerUserKey; }
set { SetPropertyValue(nameof(ProviderUserKey), ref providerUserKey, value); }
}
[Association("User-LoginInfo")]
public ApplicationUser User {
get { return user; }
set { SetPropertyValue(nameof(User), ref user, value); }
}
object ISecurityUserLoginInfo.User => User;
}

View File

@ -0,0 +1,208 @@
using DevExpress.ExpressApp.ConditionalAppearance;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
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)
{
}
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)
&& string.IsNullOrEmpty(No))
{
int nextSequence = DistributedIdGeneratorHelper.Generate(Session.DataLayer, this.GetType().FullName, "ERPrefix");
No = string.Format("KA-{0:D6}", nextSequence);
}
}
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 || CurrentPoint.Oid == Route.StartPoint.Point.Oid)
{
return CargoState.Warehouse;
}
else if (CurrentPoint != null && CurrentPoint.Oid == Route.DestinationPoint.Point.Oid)
{
return CargoState.Arrived;
}
else
{
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;
[Browsable(false)]
public string StartsFrom => Route?.StartPoint?.Name;
[Browsable(false)]
public string DestinationTo => Route?.DestinationPoint?.Name;
[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<Point> AvailablePoints
{
get
{
if (Route is null) return new XPCollection<Point>(Session);
var startPoint = Route.StartPoint.Point;
var endPoint = Route.DestinationPoint.Point;
var points = Route.Points
.OrderBy(or => or.Order)
.Select(sl => sl.Point)
.ToList();
points.Insert(0, startPoint);
points.Add(endPoint);
return new XPCollection<Point>(Session, points);
}
}
[RuleRequiredField(DefaultContexts.Save), 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> Goods
{
get
{
return GetCollection<Goods>(nameof(Goods));
}
}
[Association("Cargo-Expenses"), Aggregated]
public XPCollection<Expense> Expenses
{
get
{
return GetCollection<Expense>(nameof(Expenses));
}
}
[Association, Aggregated]
public XPCollection<CargoRoutePoints> CargoPoints
{
get
{
return GetCollection<CargoRoutePoints>(nameof(CargoPoints));
}
}
}
public enum CargoState
{
Warehouse,
InTransit,
Arrived
}
}

View File

@ -0,0 +1,54 @@
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Xpo;
using System.ComponentModel;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, CreatableItem(false), NavigationItem(false), DeferredDeletion(false)]
public class CargoRoutePoints : 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 CargoRoutePoints(Session session)
: base(session)
{
}
Cargo cargo;
DateTime? date;
Point point;
ushort order;
[Index(0), ReadOnly(true)]
public ushort Order
{
get => order;
set => SetPropertyValue(nameof(Order), ref order, value);
}
[ReadOnly(true), Index(1)]
public Point Point
{
get => point;
set => SetPropertyValue(nameof(Point), ref point, value);
}
[Index(2)]
public DateTime? Date
{
get => date;
set => SetPropertyValue(nameof(Date), ref date, value);
}
[Association, Browsable(false)]
public Cargo Cargo
{
get => cargo;
set => SetPropertyValue(nameof(Cargo), ref cargo, value);
}
}
}

View File

@ -0,0 +1,86 @@
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, NavigationItem("Transportation")]
[ImageName("Gauges")]
[DefaultProperty(nameof(Name)), FriendlyKeyProperty(nameof(Number))]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class Carrier : 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 Carrier(Session session)
: base(session)
{
}
string phone;
uint weight;
string notes;
string driver;
string number;
string name;
[Size(SizeAttribute.DefaultStringMappingFieldSize)]
public string Name
{
get => name;
set => SetPropertyValue(nameof(Name), ref name, value);
}
[Size(SizeAttribute.DefaultStringMappingFieldSize), RuleRequiredField(DefaultContexts.Save)]
public string Number
{
get => number;
set => SetPropertyValue(nameof(Number), ref number, value);
}
[Size(SizeAttribute.DefaultStringMappingFieldSize)]
public string Driver
{
get => driver;
set => SetPropertyValue(nameof(Driver), ref driver, value);
}
[Size(SizeAttribute.DefaultStringMappingFieldSize)]
public string Phone
{
get => phone;
set => SetPropertyValue(nameof(Phone), ref phone, value);
}
[ModelDefault("DisplayFormat", "{0:n2} kg")]
public uint Weight
{
get => weight;
set => SetPropertyValue(nameof(Weight), ref weight, value);
}
[Size(SizeAttribute.DefaultStringMappingFieldSize)]
public string Notes
{
get => notes;
set => SetPropertyValue(nameof(Notes), ref notes, value);
}
}
}

View File

@ -0,0 +1,104 @@
using DevExpress.Data.Filtering;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.BaseImpl.PermissionPolicy;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, NavigationItem("Clients & Goods")]
[ImageName("BO_Customer")]
[DefaultProperty(nameof(FullName))]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class Client : ApplicationUser
{ // 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 Client(Session session)
: base(session)
{
}
protected override void OnSaving()
{
base.OnSaving();
if (Session.IsNewObject(this))
{
AssignClientRole();
}
}
private void AssignClientRole()
{
// Find the "Client" role in the database
var clientRole = Session.FindObject<PermissionPolicyRole>(
CriteriaOperator.Parse("Name == ?", GlobalConstants.ClientRoleName));
// If the role is found, assign it to the user
if (clientRole != null)
{
this.Roles.Add(clientRole);
}
}
string bellik;
string telefon;
Region region;
string fullName;
//string phoneNo;
//[Size(8), ]
//public string PhoneNo
//{
// get => phoneNo;
// set => SetPropertyValue(nameof(PhoneNo), ref phoneNo, value);
//}
[Index(2)]
[Size(SizeAttribute.DefaultStringMappingFieldSize)]
public string Bellik
{
get => bellik;
set => SetPropertyValue(nameof(Bellik), ref bellik, value);
}
[Index(1)]
[Size(SizeAttribute.DefaultStringMappingFieldSize)]
public string Telefon
{
get => telefon;
set => SetPropertyValue(nameof(Telefon), ref telefon, value);
}
[Index(0)]
[Size(SizeAttribute.DefaultStringMappingFieldSize), RuleRequiredField(DefaultContexts.Save)]
public string FullName
{
get => fullName;
set => SetPropertyValue(nameof(FullName), ref fullName, value);
}
[IgnoreDataMember]
public Region Region
{
get => region;
set => SetPropertyValue(nameof(Region), ref region, value);
}
[Association("Client-Goods"), Aggregated, IgnoreDataMember]
public XPCollection<Goods> Goods
{
get
{
return GetCollection<Goods>(nameof(Goods));
}
}
}
}

View File

@ -0,0 +1,51 @@
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions]
[ImageName("BO_Contact")]
[DefaultProperty("Name")]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class Contact : 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 Contact(Session session)
: base(session)
{
}
string name;
string number;
[Size(SizeAttribute.DefaultStringMappingFieldSize), RuleRequiredField(DefaultContexts.Save)]
public string Number
{
get => number;
set => SetPropertyValue(nameof(Number), ref number, value);
}
[Size(SizeAttribute.DefaultStringMappingFieldSize), RuleRequiredField(DefaultContexts.Save)]
public string Name
{
get => name;
set => SetPropertyValue(nameof(Name), ref name, value);
}
}
}

View File

@ -0,0 +1,98 @@
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, NavigationItem("Finance")]
[ImageName("BO_Invoice")]
[DefaultProperty(nameof(No))]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class Expense : 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 Expense(Session session)
: base(session)
{
}
public override void AfterConstruction()
{
base.AfterConstruction();
ExpenseDate = DateTime.Now;
}
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)
&& string.IsNullOrEmpty(No))
{
int nextSequence = DistributedIdGeneratorHelper.Generate(Session.DataLayer, this.GetType().FullName, "ERPrefix");
No = string.Format("ÇD-{0:D6}", nextSequence);
}
}
string description;
string no;
decimal amount;
Cargo cargo;
DateTime expenseDate;
[Size(SizeAttribute.DefaultStringMappingFieldSize), RuleUniqueValue, Indexed(Unique = true), ReadOnly(true), VisibleInDetailView(false)]
public string No
{
get => no;
set => SetPropertyValue(nameof(No), ref no, value);
}
[RuleValueComparison(ValueComparisonType.GreaterThan, 0)]
[ModelDefault("DisplayFormat", "${0:#,##0.00}")]
public decimal Amount
{
get => amount;
set => SetPropertyValue(nameof(Amount), ref amount, value);
}
[RuleRequiredField(DefaultContexts.Save)]
[ModelDefault("DisplayFormat", "{0:g}"), ModelDefault("EditMask", "g")]
public DateTime ExpenseDate
{
get => expenseDate;
set => SetPropertyValue(nameof(ExpenseDate), ref expenseDate, value);
}
[Association("Cargo-Expenses"), RuleRequiredField(DefaultContexts.Save)]
public Cargo Cargo
{
get => cargo;
set => SetPropertyValue(nameof(Cargo), ref cargo, value);
}
[Size(SizeAttribute.DefaultStringMappingFieldSize), RuleRequiredField(DefaultContexts.Save)]
public string Description
{
get => description;
set => SetPropertyValue(nameof(Description), ref description, value);
}
}
}

View File

@ -0,0 +1,241 @@
using DevExpress.ExpressApp.ConditionalAppearance;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using FileSystemData.BusinessObjects;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, NavigationItem("Clients & Goods")]
[ImageName("BO_Product")]
[DefaultProperty(nameof(No))]
[Appearance("RedBackground", Priority =1, AppearanceItemType = "ViewItem", TargetItems = "Credit", Criteria = "Credit > 0", BackColor = "Red", FontColor = "White")]
[Appearance("StrikeBackground", Priority = 2, AppearanceItemType = "ViewItem", TargetItems = "Credit", Criteria = "Credit = 0", BackColor = "Green",FontColor = "White")]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class Goods : 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 Goods(Session session)
: base(session)
{
}
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)
&& string.IsNullOrEmpty(No))
{
int nextSequence = DistributedIdGeneratorHelper.Generate(Session.DataLayer, this.GetType().FullName, "ERPrefix");
No = string.Format("PA-{0:D6}", nextSequence);
}
}
public override void AfterConstruction()
{
base.AfterConstruction();
State = GoodsState.Reserved;
CreatedAt = DateTime.Now;
}
[Size(SizeAttribute.DefaultStringMappingFieldSize), NonCloneable, Indexed(Unique = true), ReadOnly(true), VisibleInDetailView(false)]
public string No
{
get => no;
set => SetPropertyValue(nameof(No), ref no, value);
}
[Size(SizeAttribute.DefaultStringMappingFieldSize), RuleRequiredField(DefaultContexts.Save), Index(2), VisibleInLookupListView(true)]
public string Name
{
get => name;
set => SetPropertyValue(nameof(Name), ref name, value);
}
[ModelDefault("DisplayFormat", "{0:g}"), ModelDefault("EditMask", "g"), ReadOnly(true)]
public DateTime CreatedAt
{
get => createdAt;
set => SetPropertyValue(nameof(CreatedAt), ref createdAt, value);
}
[RuleValueComparison(ValueComparisonType.GreaterThan, 0)]
public double Volume
{
get => volume;
set => SetPropertyValue(nameof(Volume), ref volume, value);
}
[RuleValueComparison(ValueComparisonType.GreaterThan, 0)]
public uint PlaceCount
{
get => placeCount;
set => SetPropertyValue(nameof(PlaceCount), ref placeCount, value);
}
[RuleValueComparison(ValueComparisonType.GreaterThan, 0)]
public uint PackageCount
{
get => packageCount;
set => SetPropertyValue(nameof(PackageCount), ref packageCount, value);
}
[Size(SizeAttribute.DefaultStringMappingFieldSize), IgnoreDataMember]
public string PackingType
{
get => packingType;
set => SetPropertyValue(nameof(PackingType), ref packingType, value);
}
public DateTime ReceivedAt
{
get => receivedAt;
set => SetPropertyValue(nameof(ReceivedAt), ref receivedAt, value);
}
[ModelDefault("DisplayFormat", "${0:#,##0.00}")]
public decimal Price
{
get => price;
set => SetPropertyValue(nameof(Price), ref price, value);
}
public uint Height
{
get => height;
set => SetPropertyValue(nameof(Height), ref height, value);
}
public uint Width
{
get => width;
set => SetPropertyValue(nameof(Width), ref width, value);
}
public uint Depth
{
get => depth;
set => SetPropertyValue(nameof(Depth), ref depth, value);
}
//[RuleRequiredField(DefaultContexts.Save), Index(1)]
//public Shop Shop
//{
// get => shop;
// set => SetPropertyValue(nameof(Shop), ref shop, value);
//}
[Size(SizeAttribute.DefaultStringMappingFieldSize)]
public string ShopNo
{
get => shopNo;
set => SetPropertyValue(nameof(ShopNo), ref shopNo, value);
}
[Aggregated, ExpandObjectMembers(ExpandObjectMembers.Never), ImmediatePostData]
public FileSystemStoreObject Image1
{
get { return GetPropertyValue<FileSystemStoreObject>("Image1"); }
set { SetPropertyValue<FileSystemStoreObject>("Image1", value); }
}
[Aggregated, ExpandObjectMembers(ExpandObjectMembers.Never), ImmediatePostData]
public FileSystemStoreObject Image2
{
get { return GetPropertyValue<FileSystemStoreObject>("Image2"); }
set { SetPropertyValue<FileSystemStoreObject>("Image2", value); }
}
[Aggregated, ExpandObjectMembers(ExpandObjectMembers.Never), ImmediatePostData]
public FileSystemStoreObject Image3
{
get { return GetPropertyValue<FileSystemStoreObject>("Image3"); }
set { SetPropertyValue<FileSystemStoreObject>("Image3", value); }
}
[Association("Goods-Payments"), Aggregated]
public XPCollection<Payment> Payments
{
get
{
return GetCollection<Payment>(nameof(Payments));
}
}
[Association("Goods-GoodsImages"), Aggregated]
public XPCollection<GoodsImage> Images
{
get { return GetCollection<GoodsImage>(nameof(Images)); }
}
[Index(0), VisibleInLookupListView(true), VisibleInDetailView(true), IgnoreDataMember]
[Association("Client-Goods"), RuleRequiredField(DefaultContexts.Save)]
public Client Client
{
get => client;
set => SetPropertyValue(nameof(Client), ref client, value);
}
[VisibleInDetailView(false)]
[ModelDefault("DisplayFormat", "${0:#,##0.00}")]
public decimal TotalPayment => Payments.Sum(ps => ps.Amount);
[VisibleInDetailView(false)]
[ModelDefault("DisplayFormat", "${0:#,##0.00}")]
public decimal Credit => Price - TotalPayment;
public GoodsState State
{
get => state;
set => SetPropertyValue(nameof(State), ref state, value);
}
string shopNo;
DateTime createdAt;
GoodsState state;
//Shop shop;
uint depth;
uint width;
uint height;
uint packageCount;
string packingType;
DateTime receivedAt;
decimal price;
uint placeCount;
double volume;
string name;
string no;
Client client;
Cargo cargo;
[Association("Cargo-Goods")]
public Cargo Cargo
{
get => cargo;
set => SetPropertyValue(nameof(Cargo), ref cargo, value);
}
}
public enum GoodsState
{
Reserved,
Received,
Delivered,
}
}

View File

@ -0,0 +1,39 @@
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Xpo;
using FileSystemData.BusinessObjects;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, CreatableItem(false), NavigationItem(false), DeferredDeletion(false)]
[FileAttachment(nameof(File))]
//[ImageName("BO_Contact")]
//[DefaultProperty("DisplayMemberNameForLookupEditorsOfThisType")]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class GoodsImage : FileSystemStoreObject
{ // 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 GoodsImage(Session session)
: base(session)
{
}
private Goods goods;
[Association("Goods-GoodsImages")]
public Goods Goods
{
get { return goods; }
set { SetPropertyValue(nameof(Goods), ref goods, value); }
}
private FileData file;
[FileTypeFilter("ImageFiles", 1, "*.png", "*.jpg")]
[Aggregated, ExpandObjectMembers(ExpandObjectMembers.Never), ImmediatePostData]
public FileData File
{
get { return file; }
set { SetPropertyValue(nameof(File), ref file, value); }
}
}
}

View File

@ -0,0 +1,95 @@
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, NavigationItem("Finance")]
[ImageName("Refund")]
[DefaultProperty(nameof(No))]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class Payment : 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 Payment(Session session)
: base(session)
{
}
public override void AfterConstruction()
{
base.AfterConstruction();
PaymentDate = DateTime.Now;
}
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)
&& string.IsNullOrEmpty(No))
{
int nextSequence = DistributedIdGeneratorHelper.Generate(Session.DataLayer, this.GetType().FullName, "ERPrefix");
No = string.Format("GD-{0:D6}", nextSequence);
}
}
string description;
string no;
decimal amount;
Goods goods;
DateTime paymentDate;
[Size(SizeAttribute.DefaultStringMappingFieldSize), RuleUniqueValue,Indexed(Unique = true), RuleUniqueValue, ReadOnly(true), VisibleInDetailView(false)]
public string No
{
get => no;
set => SetPropertyValue(nameof(No), ref no, value);
}
[RuleValueComparison(ValueComparisonType.GreaterThan, 0)]
[ModelDefault("DisplayFormat", "${0:#,##0.00}")]
public decimal Amount
{
get => amount;
set => SetPropertyValue(nameof(Amount), ref amount, value);
}
[RuleRequiredField(DefaultContexts.Save)]
[ModelDefault("DisplayFormat", "{0:g}"), ModelDefault("EditMask", "g")]
public DateTime PaymentDate
{
get => paymentDate;
set => SetPropertyValue(nameof(PaymentDate), ref paymentDate, value);
}
[Size(SizeAttribute.DefaultStringMappingFieldSize)]
public string Description
{
get => description;
set => SetPropertyValue(nameof(Description), ref description, value);
}
[RuleRequiredField(DefaultContexts.Save), ImmediatePostData]
[Association("Goods-Payments")]
public Goods Goods
{
get => goods;
set => SetPropertyValue(nameof(Goods), ref goods, value);
}
public Client Client => Goods?.Client;
}
}

View File

@ -0,0 +1,58 @@
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, NavigationItem("Places")]
[ImageName("Travel_MapPointer")]
[DefaultProperty(nameof(Name))]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class Point : 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 Point(Session session)
: base(session)
{
}
double longitude;
double latitude;
string name;
[Size(SizeAttribute.DefaultStringMappingFieldSize), RuleRequiredField(DefaultContexts.Save), Indexed, RuleUniqueValue]
public string Name
{
get => name;
set => SetPropertyValue(nameof(Name), ref name, value);
}
//todo edit mask
public double Latitude
{
get => latitude;
set => SetPropertyValue(nameof(Latitude), ref latitude, value);
}
//todo edit mask
public double Longitude
{
get => longitude;
set => SetPropertyValue(nameof(Longitude), ref longitude, value);
}
}
}

View File

@ -0,0 +1,26 @@
Folder Description
The "BusinessObjects" project folder is intended for storing code of your data model.
In XAF, a business object can be implemented as an ORM-based persistent class
or a non-persistent POCO.
Relevant Documentation
Business Model Design
https://docs.devexpress.com/eXpressAppFramework/113461
Non-Persistent Objects
https://docs.devexpress.com/eXpressAppFramework/116516
Data Types Supported by built-in Editors
https://docs.devexpress.com/eXpressAppFramework/113014
Ways to Add a Business Class (XPO)
https://docs.devexpress.com/eXpressAppFramework/112847
Ways to Implement Business Logic
https://docs.devexpress.com/eXpressAppFramework/113710
Debugging, Unit and Functional Testing
https://docs.devexpress.com/eXpressAppFramework/112572

View File

@ -0,0 +1,41 @@
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, NavigationItem("Places")]
[ImageName("BO_Country_v92")]
[DefaultProperty(nameof(Name))]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class Region : 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 Region(Session session)
: base(session)
{
}
string name;
[Size(SizeAttribute.DefaultStringMappingFieldSize), Indexed, RuleUniqueValue, RuleRequiredField(DefaultContexts.Save)]
public string Name
{
get => name;
set => SetPropertyValue(nameof(Name), ref name, value);
}
}
}

View File

@ -0,0 +1,61 @@
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, NavigationItem("Transportation")]
[ImageName("GeoPointMaps")]
[DefaultProperty(nameof(Title))]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class Route : 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 Route(Session session)
: base(session)
{
}
Warehouse destinationPoint;
Warehouse startPoint;
string title;
[Size(SizeAttribute.DefaultStringMappingFieldSize), RuleRequiredField(DefaultContexts.Save)]
public string Title
{
get => title;
set => SetPropertyValue(nameof(Title), ref title, value);
}
[RuleRequiredField(DefaultContexts.Save)]
public Warehouse StartPoint
{
get => startPoint;
set => SetPropertyValue(nameof(StartPoint), ref startPoint, value);
}
[RuleRequiredField(DefaultContexts.Save)]
public Warehouse DestinationPoint
{
get => destinationPoint;
set => SetPropertyValue(nameof(DestinationPoint), ref destinationPoint, value);
}
[Association("Route-RoutePoints"), Aggregated]
public XPCollection<RoutePoint> Points
{
get
{
return GetCollection<RoutePoint>(nameof(Points));
}
}
}
}

View File

@ -0,0 +1,60 @@
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, NavigationItem(false)]
[DeferredDeletion(false), CreatableItem(false)]
//[ImageName("BO_Contact")]
//[DefaultProperty("DisplayMemberNameForLookupEditorsOfThisType")]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class RoutePoint : 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 RoutePoint(Session session)
: base(session)
{
}
Point point;
ushort order;
Route route;
[Association("Route-RoutePoints")]
public Route Route
{
get => route;
set => SetPropertyValue(nameof(Route), ref route, value);
}
[RuleValueComparison(ValueComparisonType.LessThan, ushort.MaxValue)]
public ushort Order
{
get => order;
set => SetPropertyValue(nameof(Order), ref order, value);
}
[RuleRequiredField(DefaultContexts.Save)]
public Point Point
{
get => point;
set => SetPropertyValue(nameof(Point), ref point, value);
}
}
}

View File

@ -0,0 +1,61 @@
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, NavigationItem(false), CreatableItem(false)]
[ImageName("Shopping_Store")]
[DefaultProperty(nameof(No))]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class Shop : 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 Shop(Session session)
: base(session)
{
}
string phone;
string name;
string no;
[Size(SizeAttribute.DefaultStringMappingFieldSize), RuleRequiredField(DefaultContexts.Save), RuleUniqueValue]
public string No
{
get => no;
set => SetPropertyValue(nameof(No), ref no, value);
}
[Size(SizeAttribute.DefaultStringMappingFieldSize)]
public string Name
{
get => name;
set => SetPropertyValue(nameof(Name), ref name, value);
}
[Size(SizeAttribute.DefaultStringMappingFieldSize)]
public string Phone
{
get => phone;
set => SetPropertyValue(nameof(Phone), ref phone, value);
}
}
}

View File

@ -0,0 +1,64 @@

using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace DurnyklyYol.Module.BusinessObjects
{
[DefaultClassOptions, NavigationItem("Places")]
[ImageName("BO_Organization")]
[DefaultProperty(nameof(Name))]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/#eXpressAppFramework/CustomDocument112701).
public class Warehouse : 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 Warehouse(Session session)
: base(session)
{
}
string name;
Point point;
string address;
Region region;
[Size(SizeAttribute.DefaultStringMappingFieldSize), RuleRequiredField(DefaultContexts.Save)]
public string Name
{
get => name;
set => SetPropertyValue(nameof(Name), ref name, value);
}
[RuleRequiredField(DefaultContexts.Save)]
public Region Region
{
get => region;
set => SetPropertyValue(nameof(Region), ref region, value);
}
[Size(SizeAttribute.Unlimited)]
public string Address
{
get => address;
set => SetPropertyValue(nameof(Address), ref address, value);
}
[RuleRequiredField(DefaultContexts.Save)]
public Point Point
{
get => point;
set => SetPropertyValue(nameof(Point), ref point, value);
}
}
}

View File

@ -0,0 +1,36 @@
namespace DurnyklyYol.Module.Controllers
{
partial class GoodsController
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,53 @@
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.ExpressApp.Editors;
using DevExpress.ExpressApp.Layout;
using DevExpress.ExpressApp.Model.NodeGenerators;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.SystemModule;
using DevExpress.ExpressApp.Templates;
using DevExpress.ExpressApp.Updating;
using DevExpress.ExpressApp.Utils;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.Validation;
using DurnyklyYol.Module.BusinessObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DurnyklyYol.Module.Controllers
{
// For more typical usage scenarios, be sure to check out https://documentation.devexpress.com/eXpressAppFramework/clsDevExpressExpressAppViewControllertopic.aspx.
public partial class GoodsController : ObjectViewController<ListView, Goods>
{
public GoodsController()
{
InitializeComponent();
// Target required Views (via the TargetXXX properties) and create their Actions.
}
protected override void OnActivated()
{
base.OnActivated();
if (View is ListView listView)
{
if (IsCurrentUserInRoleOperator.IsCurrentUserInRole(GlobalConstants.ClientRoleName))
{
listView.CollectionSource.Criteria["Filter1"] = CriteriaOperator.Parse("Client.Oid=CurrentUserId()");
}
}
//var gridListEditor = View.Editor as DevExpress.ExpressApp.Win.Editors.GridListEditor;
//if (gridListEditor != null)
//{
// var gridView = gridListEditor.GridView;
// gridView.Columns["Country"].GroupIndex = 0;
// gridView.Columns["City"].GroupIndex = 1;
// gridView.Columns["Company"].GroupIndex = 2;
//}
}
}
}

View File

@ -0,0 +1,25 @@
Folder Description
The "Controllers" project folder is intended for storing platform-agnostic Controller classes
that can change the default XAF application flow and add new features.
Relevant Documentation
Controllers and Actions
https://docs.devexpress.com/eXpressAppFramework/112623
Implement Custom Controllers
https://docs.devexpress.com/eXpressAppFramework/112621
Define the Scope of Controllers and Actions
https://docs.devexpress.com/eXpressAppFramework/113103
Ways to Show a View
https://docs.devexpress.com/eXpressAppFramework/112803
Ways to Implement Business Logic
https://docs.devexpress.com/eXpressAppFramework/113710
Debugging, Unit and Functional Testing
https://docs.devexpress.com/eXpressAppFramework/112572

View File

@ -0,0 +1,23 @@
Folder Description
The "DatabaseUpdate" project folder is intended for storing code that supplies
initial data (default User objects, etc) and handles a database update when the
application version changes.
Relevant Documentation
Supply Initial Data (XPO)
https://docs.devexpress.com/eXpressAppFramework/112788
ModuleUpdater Class
https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.Updating.ModuleUpdater
Application Update
https://docs.devexpress.com/eXpressAppFramework/113239
How to: Update the Database Structure after the Persistent Class or Property Was Renamed or Removed (XPO)
https://docs.devexpress.com/eXpressAppFramework/113254
Debugging, Unit and Functional Testing
https://docs.devexpress.com/eXpressAppFramework/112572

View File

@ -0,0 +1,116 @@
using DevExpress.ExpressApp;
using DevExpress.Data.Filtering;
using DevExpress.Persistent.Base;
using DevExpress.ExpressApp.Updating;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.SystemModule;
using DevExpress.ExpressApp.Security.Strategy;
using DevExpress.Xpo;
using DevExpress.ExpressApp.Xpo;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.BaseImpl.PermissionPolicy;
using DurnyklyYol.Module.BusinessObjects;
using Microsoft.Extensions.DependencyInjection;
namespace DurnyklyYol.Module.DatabaseUpdate;
// For more typical usage scenarios, be sure to check out https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.Updating.ModuleUpdater
public class Updater : ModuleUpdater {
public Updater(IObjectSpace objectSpace, Version currentDBVersion) :
base(objectSpace, currentDBVersion) {
}
public override void UpdateDatabaseAfterUpdateSchema() {
base.UpdateDatabaseAfterUpdateSchema();
//string name = "MyName";
//DomainObject1 theObject = ObjectSpace.FirstOrDefault<DomainObject1>(u => u.Name == name);
//if(theObject == null) {
// theObject = ObjectSpace.CreateObject<DomainObject1>();
// theObject.Name = name;
//}
// The code below creates users and roles for testing purposes only.
// In production code, you can create users and assign roles to them automatically, as described in the following help topic:
// https://docs.devexpress.com/eXpressAppFramework/119064/data-security-and-safety/security-system/authentication
#if !RELEASE
// If a role doesn't exist in the database, create this role
var defaultRole = CreateClientRole();
var adminRole = CreateAdminRole();
ObjectSpace.CommitChanges(); //This line persists created object(s).
UserManager userManager = ObjectSpace.ServiceProvider.GetRequiredService<UserManager>();
// If a user named 'User' doesn't exist in the database, create this user
if(userManager.FindUserByName<ApplicationUser>(ObjectSpace, "User") == null) {
// Set a password if the standard authentication type is used
string EmptyPassword = "";
_ = userManager.CreateUser<ApplicationUser>(ObjectSpace, "User", EmptyPassword, (user) => {
// Add the Users role to the user
user.Roles.Add(defaultRole);
});
}
// If a user named 'Admin' doesn't exist in the database, create this user
if(userManager.FindUserByName<ApplicationUser>(ObjectSpace, "Admin") == null) {
// Set a password if the standard authentication type is used
string EmptyPassword = "";
_ = userManager.CreateUser<ApplicationUser>(ObjectSpace, "Admin", EmptyPassword, (user) => {
// Add the Administrators role to the user
user.Roles.Add(adminRole);
});
}
ObjectSpace.CommitChanges(); //This line persists created object(s).
#endif
}
public override void UpdateDatabaseBeforeUpdateSchema() {
base.UpdateDatabaseBeforeUpdateSchema();
//if(CurrentDBVersion < new Version("1.1.0.0") && CurrentDBVersion > new Version("0.0.0.0")) {
// RenameColumn("DomainObject1Table", "OldColumnName", "NewColumnName");
//}
}
private PermissionPolicyRole CreateAdminRole() {
PermissionPolicyRole adminRole = ObjectSpace.FirstOrDefault<PermissionPolicyRole>(r => r.Name == GlobalConstants.AdminRoleName);
if(adminRole == null) {
adminRole = ObjectSpace.CreateObject<PermissionPolicyRole>();
adminRole.Name = GlobalConstants.AdminRoleName;
adminRole.IsAdministrative = true;
}
return adminRole;
}
private PermissionPolicyRole CreateClientRole() {
PermissionPolicyRole clRole = ObjectSpace.FirstOrDefault<PermissionPolicyRole>(role => role.Name == GlobalConstants.ClientRoleName);
if(clRole == null) {
clRole = ObjectSpace.CreateObject<PermissionPolicyRole>();
clRole.Name = GlobalConstants.ClientRoleName;
clRole.AddObjectPermissionFromLambda<ApplicationUser>(SecurityOperations.Read, cm => cm.Oid == (Guid)CurrentUserIdOperator.CurrentUserId(), SecurityPermissionState.Allow);
clRole.AddObjectPermissionFromLambda<Client>(SecurityOperations.Read, cm => cm.Oid == (Guid)CurrentUserIdOperator.CurrentUserId(), SecurityPermissionState.Allow);
clRole.AddObjectPermissionFromLambda<Goods>(SecurityOperations.Read, cm => cm.Client.Oid == (Guid)CurrentUserIdOperator.CurrentUserId(), SecurityPermissionState.Allow);
clRole.AddNavigationPermission(@"Application/NavigationItems/Items/Default/Items/MyDetails", SecurityPermissionState.Allow);
clRole.AddNavigationPermission(@"Application/NavigationItems/Items/Clients & Goods/Items/Goods", SecurityPermissionState.Allow);
clRole.AddMemberPermissionFromLambda<ApplicationUser>(SecurityOperations.Write, "ChangePasswordOnFirstLogon", cm => cm.Oid == (Guid)CurrentUserIdOperator.CurrentUserId(), SecurityPermissionState.Allow);
clRole.AddMemberPermissionFromLambda<ApplicationUser>(SecurityOperations.Write, "StoredPassword", cm => cm.Oid == (Guid)CurrentUserIdOperator.CurrentUserId(), SecurityPermissionState.Allow);
clRole.AddTypePermissionsRecursively<PermissionPolicyRole>(SecurityOperations.Read, SecurityPermissionState.Allow);
clRole.AddTypePermission<Shop>(SecurityOperations.Read, SecurityPermissionState.Allow);
clRole.AddTypePermission<Contact>(SecurityOperations.Read, SecurityPermissionState.Allow);
clRole.AddTypePermission<Cargo>(SecurityOperations.Read, SecurityPermissionState.Allow);
clRole.AddTypePermission<Payment>(SecurityOperations.Read, SecurityPermissionState.Allow);
clRole.AddTypePermission<Point>(SecurityOperations.Read, SecurityPermissionState.Allow);
clRole.AddTypePermission<Route>(SecurityOperations.Read, SecurityPermissionState.Allow);
clRole.AddTypePermission<RoutePoint>(SecurityOperations.Read, SecurityPermissionState.Allow);
clRole.AddTypePermission<Carrier>(SecurityOperations.Read, SecurityPermissionState.Allow);
clRole.AddTypePermission<Warehouse>(SecurityOperations.Read, SecurityPermissionState.Allow);
//clRole.AddObjectPermission<ModelDifference>(SecurityOperations.ReadWriteAccess, "UserId = ToStr(CurrentUserId())", SecurityPermissionState.Deny);
//clRole.AddObjectPermission<ModelDifferenceAspect>(SecurityOperations.ReadWriteAccess, "Owner.UserId = ToStr(CurrentUserId())", SecurityPermissionState.Deny);
//clRole.AddTypePermissionsRecursively<ModelDifference>(SecurityOperations.Create, SecurityPermissionState.Allow);
// clRole.AddTypePermissionsRecursively<ModelDifferenceAspect>(SecurityOperations.Create, SecurityPermissionState.Allow);
}
return clRole;
}
}

View File

@ -0,0 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<Deterministic>false</Deterministic>
<AssemblyVersion>1.0.*</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<Configurations>Debug;Release;EasyTest</Configurations>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<None Remove="Model.DesignedDiffs.Localization.tk-TM.xafml" />
<None Remove="Model.DesignedDiffs.xafml" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Model.DesignedDiffs.Localization.tk-TM.xafml">
<DependentUpon>Model.DesignedDiffs.xafml</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Model.DesignedDiffs.xafml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="DevExpress.ExpressApp" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.CodeAnalysis" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.ConditionalAppearance" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Objects" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.PivotGrid" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.ReportsV2" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Security" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Security.Xpo" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Validation" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.ViewVariantsModule" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Xpo" Version="24.1.4" />
<PackageReference Include="DevExpress.Persistent.Base" Version="24.1.4" />
<PackageReference Include="DevExpress.Persistent.BaseImpl.Xpo" Version="24.1.4" />
<PackageReference Include="Azure.Identity" Version="1.11.4" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.34.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FileSystemData\FileSystemData.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="UnusableNodes.xml">
<DependentUpon>Model.DesignedDiffs.xafml</DependentUpon>
</None>
<None Update="UnusableNodes_tk-TM.xml">
<DependentUpon>Model.DesignedDiffs.xafml</DependentUpon>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DurnyklyYol.Module
{
public static class GlobalConstants
{
public const string ClientRoleName = "Client";
public const string AdminRoleName = "Administrators";
}
}

View File

@ -0,0 +1,12 @@
Folder Description
The "Images" project folder is intended for storing custom image files.
Relevant Documentation
Add and Override Images
https://docs.devexpress.com/eXpressAppFramework/112792
Assign a Custom Image
https://docs.devexpress.com/eXpressAppFramework/112744

View File

@ -0,0 +1,181 @@
<?xml version="1.0" encoding="utf-8"?>
<Application>
<BOModel>
<Class Name="DurnyklyYol.Module.BusinessObjects.Cargo" Caption="Kargo">
<OwnMembers>
<Member Name="No" Caption="№" />
<Member Name="ArrivedAt" Caption="Geliş Senesi" />
<Member Name="Carrier" Caption="Ulagy" />
<Member Name="CurrentPoint" Caption="Häzirki ýeri" />
<Member Name="CurrentProfit" Caption="Peýdasy" />
<Member Name="ExpectedProfit" Caption="Garaşylýan peýda" />
<Member Name="Expenses" Caption="Çykdaýjylar" />
<Member Name="Goods" Caption="Ýükler" />
<Member Name="PayedTotal" Caption="Jemi tölenen" />
<Member Name="Route" Caption="Ugry" />
<Member Name="StartedAt" Caption="Ugraýan senesi" />
<Member Name="State" Caption="Statusy" />
<Member Name="TotalСredit" Caption="Galan tölegi (algy)" />
<Member Name="TotalExpenseAmount" Caption="Umumy çykdaýjy" />
<Member Name="TotalPriceAmount" Caption="Jemi baha" />
<Member Name="TotalWeight" Caption="Agyrlygy" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.Carrier" Caption="Ulag">
<OwnMembers>
<Member Name="Driver" Caption="Sürüji" />
<Member Name="Name" Caption="Ulag ady" />
<Member Name="Notes" Caption="Bellikler" />
<Member Name="Number" Caption="Belgisi" />
<Member Name="Phone" Caption="Telefony" />
<Member Name="Weight" Caption="Agyrlygy" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.Client" Caption="Müşderi">
<OwnMembers>
<Member Name="FullName" Caption="Doly ady" />
<Member Name="Goods" Caption="Ýükleri" />
<Member Name="Region" Caption="Regiony" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.Expense" Caption="Çykdaýjy">
<OwnMembers>
<Member Name="Amount" Caption="Möçberi" />
<Member Name="Cargo" Caption="Kargo" />
<Member Name="Description" Caption="Beýany" />
<Member Name="ExpenseDate" Caption="Senesi" />
<Member Name="No" Caption="№" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.Goods" Caption="Ýük">
<OwnMembers>
<Member Name="Client" Caption="Müşderi" />
<Member Name="Name" Caption="Ýüküň Ady" />
<Member Name="Cargo" Caption="Kargo" />
<Member Name="CreatedAt" Caption="Döredilen senesi" />
<Member Name="Credit" Caption="Galan tölegi (algy)" />
<Member Name="Depth" Caption="Uzynlygy" />
<Member Name="Height" Caption="Boýy" />
<Member Name="Image1" Caption="Surat 1" />
<Member Name="Image2" Caption="Surat 2" />
<Member Name="Image3" Caption="Surat 3" />
<Member Name="Images" Caption="Suratlary" />
<Member Name="No" Caption="№" />
<Member Name="PackageCount" Caption="Gap sany" />
<Member Name="PackingType" Caption="Gaplama görnüşi" />
<Member Name="Payments" Caption="Tölegleri" />
<Member Name="PlaceCount" Caption="Ýer sany" />
<Member Name="Price" Caption="Bahasy" />
<Member Name="ReceivedAt" Caption="Kabul edilen senesi" />
<Member Name="ShopNo" Caption="Magazin No" />
<Member Name="State" Caption="Statusy" />
<Member Name="TotalPayment" Caption="Jemi tölenen" />
<Member Name="Volume" Caption="Göwrümi" />
<Member Name="Width" Caption="Ini" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.GoodsImage" Caption="Surat">
<OwnMembers>
<Member Name="Goods" Caption="Ýük" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.Payment" Caption="Töleg">
<OwnMembers>
<Member Name="Amount" Caption="Möçberi" />
<Member Name="Client" Caption="Müşderi" />
<Member Name="Description" Caption="Beýany" />
<Member Name="Goods" Caption="Ýük" />
<Member Name="No" Caption="№" />
<Member Name="PaymentDate" Caption="Senesi" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.Point" Caption="Nokat">
<OwnMembers>
<Member Name="Name" Caption="Ady" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.Region">
<OwnMembers>
<Member Name="Name" Caption="Ady" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.Route" Caption="Ugur">
<OwnMembers>
<Member Name="DestinationPoint" Caption="Barmaly nokady" />
<Member Name="Points" Caption="Nokatlary" />
<Member Name="StartPoint" Caption="Başlangyç nokady" />
<Member Name="Title" Caption="Ady" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.RoutePoint" Caption="Ugur-Nokat">
<OwnMembers>
<Member Name="Order" Caption="Tertibi" />
<Member Name="Point" Caption="Nokady" />
<Member Name="Route" Caption="Ugur" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.Shop" Caption="Dükan">
<OwnMembers>
<Member Name="Name" Caption="Ady" />
<Member Name="No" Caption="№" />
<Member Name="Phone" Caption="Telefony" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.Warehouse" Caption="Ammar">
<OwnMembers>
<Member Name="Address" Caption="Addresi" />
<Member Name="Name" Caption="Ady" />
<Member Name="Point" Caption="Nokady" />
<Member Name="Region" Caption="Regiony" />
</OwnMembers>
</Class>
</BOModel>
<Localization>
<LocalizationGroup Name="Enums">
<LocalizationGroup Name="DurnyklyYol.Module.BusinessObjects.CargoState">
<LocalizationItem Name="Arrived" Value="Geldi" />
<LocalizationItem Name="InTransit" Value="Ýolda" />
<LocalizationItem Name="Warehouse" Value="Ýüklenýär" />
</LocalizationGroup>
<LocalizationGroup Name="DurnyklyYol.Module.BusinessObjects.GoodsState">
<LocalizationItem Name="Delivered" Value="Tabşyryldy" />
<LocalizationItem Name="Received" Value="Kabul edildi" />
<LocalizationItem Name="Reserved" Value="Sargyt edildi" />
</LocalizationGroup>
</LocalizationGroup>
</Localization>
<NavigationItems>
<Items>
<Item Id="Clients &amp; Goods" Caption="Müşderiler &amp; Ýükler">
<Items>
<Item Id="Client_ListView" Caption="Müşderiler" />
<Item Id="Goods_ListView" Caption="Ýükler" />
</Items>
</Item>
<Item Id="Transportation" Caption="Logistika">
<Items>
<Item Id="Carrier_ListView" Caption="Ulaglar" />
<Item Id="Route_ListView" Caption="Ugurlar" />
</Items>
</Item>
<Item Id="Places" Caption="Ýerler">
<Items>
<Item Id="Point_ListView" Caption="Nokatlar" />
<Item Id="Region_ListView" Caption="Regionlar" />
<Item Id="Warehouse_ListView" Caption="Ammarlar" />
</Items>
</Item>
<Item Id="Finance" Caption="Finans">
<Items>
<Item Id="Expense_ListView" Caption="Çykdaýjylar" />
<Item Id="Payment_ListView" Caption="Tölegler" />
</Items>
</Item>
<Item Id="Reports" Caption="Hasabat">
<Items>
<Item Id="ReportsV2" Caption="Hasabatlar" />
</Items>
</Item>
</Items>
</NavigationItems>
</Application>

View File

@ -0,0 +1,201 @@
<?xml version="1.0" encoding="utf-8"?>
<Application Title="DurnyklyYol">
<BOModel>
<Class Name="DevExpress.Persistent.BaseImpl.PermissionPolicy.PermissionPolicyUser" Caption="Base User" />
<Class Name="DurnyklyYol.Module.BusinessObjects.Client">
<OwnMembers>
<Member Name="Goods" LookupEditorMode="Auto" />
</OwnMembers>
</Class>
</BOModel>
<NavigationItems NavigationStyle="Accordion">
<Items>
<Item Id="Clients &amp; Goods" Index="0" />
<Item Id="Transportation" Index="2" />
<Item Id="Places" Index="3" />
<Item Id="Finance" Index="4" />
<Item Id="Reports" Index="5" />
</Items>
</NavigationItems>
<Options>
<LayoutManagerOptions RequiredFieldMark="*" />
</Options>
<SchemaModules>
<SchemaModule Name="SystemModule" Version="24.1.4.0" IsNewNode="True" />
</SchemaModules>
<Views>
<ListView Id="ApplicationUser_ListView" Caption="Users" />
<DetailView Id="Cargo_DetailView">
<Layout>
<LayoutGroup Id="Main" RelativeSize="100">
<LayoutGroup Id="SimpleEditors" RelativeSize="18.78048780487805">
<LayoutGroup Id="Cargo" ShowCaption="False" RelativeSize="100">
<LayoutGroup Id="Cargo_col1" RelativeSize="50">
<LayoutItem Id="State" RelativeSize="13.636363636363637" />
<LayoutItem Id="StartedAt" RelativeSize="13.636363636363637" />
<LayoutItem Id="ArrivedAt" RelativeSize="13.636363636363637" />
<LayoutItem Id="TotalPriceAmount" RelativeSize="13.636363636363637" />
<LayoutItem Id="TotalExpenseAmount" RelativeSize="13.636363636363637" />
<LayoutItem Id="PayedTotal" RelativeSize="15.584415584415584" />
</LayoutGroup>
<LayoutGroup Id="Cargo_col2" RelativeSize="50">
<LayoutItem Id="TotalСredit" RelativeSize="16.233766233766232" />
<LayoutItem Id="ExpectedProfit" RelativeSize="13.636363636363637" />
<LayoutItem Id="CurrentProfit" RelativeSize="13.636363636363637" />
<LayoutItem Id="Route" RelativeSize="13.636363636363637" />
<LayoutItem Id="CurrentPoint" RelativeSize="13.636363636363637" />
<LayoutItem Id="Carrier" RelativeSize="29.22077922077922" />
</LayoutGroup>
</LayoutGroup>
</LayoutGroup>
<TabbedGroup Id="Tabs" RelativeSize="81.21951219512195">
<LayoutGroup Id="Goods" RelativeSize="100">
<LayoutItem Id="Goods" RelativeSize="100" />
</LayoutGroup>
<LayoutGroup Id="Expenses" RelativeSize="100">
<LayoutItem Id="Expenses" RelativeSize="100" />
</LayoutGroup>
</TabbedGroup>
</LayoutGroup>
</Layout>
</DetailView>
<ListView Id="Cargo_Expenses_ListView" DataAccessMode="Server" AllowDelete="False" AllowLink="False" AllowNew="False" />
<ListView Id="Cargo_Goods_ListView" AllowDelete="False" AllowLink="True" AllowNew="False" DataAccessMode="Server">
<Columns>
<ColumnInfo Id="CreatedAt" Index="-1" />
<ColumnInfo Id="PackingType" Index="-1" />
<ColumnInfo Id="State" Index="-1" />
<ColumnInfo Id="Volume" Index="4" />
<ColumnInfo Id="PlaceCount" Index="5" />
<ColumnInfo Id="PackageCount" Index="6" />
<ColumnInfo Id="ReceivedAt" Index="7" />
<ColumnInfo Id="Price" Index="8" />
<ColumnInfo Id="Height" Index="9" />
<ColumnInfo Id="Width" Index="10" />
<ColumnInfo Id="Depth" Index="11" />
<ColumnInfo Id="TotalPayment" Index="12" />
<ColumnInfo Id="Credit" Index="13" />
</Columns>
</ListView>
<ListView Id="Cargo_ListView" DataAccessMode="Server">
<Columns>
<ColumnInfo Id="Route" Index="-1" />
<ColumnInfo Id="No" OwnerBand="Info" />
<ColumnInfo Id="State" OwnerBand="Info" />
<ColumnInfo Id="StartedAt" OwnerBand="Info" />
<ColumnInfo Id="ArrivedAt" OwnerBand="Info" />
<ColumnInfo Id="TotalPriceAmount" OwnerBand="Finance" />
<ColumnInfo Id="TotalExpenseAmount" OwnerBand="Finance" />
<ColumnInfo Id="PayedTotal" OwnerBand="Finance" />
<ColumnInfo Id="TotalСredit" OwnerBand="Finance" />
<ColumnInfo Id="ExpectedProfit" OwnerBand="Finance" />
<ColumnInfo Id="CurrentProfit" OwnerBand="Finance" />
<ColumnInfo Id="CurrentPoint" OwnerBand="Info" />
<ColumnInfo Id="Carrier" OwnerBand="Info" />
</Columns>
<BandsLayout Enable="True">
<Band Id="Finance" Caption="Finance" IsNewNode="True" />
<Band Id="Info" Caption="Info" IsNewNode="True" />
</BandsLayout>
</ListView>
<ListView Id="Cargo_LookupListView" AllowDelete="False" AllowNew="False" AllowLink="True" DataAccessMode="Server" />
<ListView Id="Carrier_ListView" DataAccessMode="Server" />
<ListView Id="Carrier_LookupListView" AllowDelete="False" DataAccessMode="Server" />
<DetailView Id="Client_DetailView">
<Layout>
<LayoutGroup Id="Main">
<TabbedGroup Id="Tabs">
<LayoutGroup Id="Roles" Index="-1" Removed="True" />
</TabbedGroup>
</LayoutGroup>
</Layout>
</DetailView>
<ListView Id="Client_Goods_ListView" DataAccessMode="Server" AllowUnlink="False" AllowDelete="False" AllowNew="False" AllowLink="True">
<Columns>
<ColumnInfo Id="Depth" Index="-1" />
<ColumnInfo Id="Height" Index="-1" />
<ColumnInfo Id="PackageCount" Index="-1" />
<ColumnInfo Id="PackingType" Index="-1" />
<ColumnInfo Id="PlaceCount" Index="-1" />
<ColumnInfo Id="Width" Index="-1" />
<ColumnInfo Id="ReceivedAt" Index="5" />
<ColumnInfo Id="Price" Index="6" />
<ColumnInfo Id="TotalPayment" Index="7" />
<ColumnInfo Id="Credit" Index="8" />
<ColumnInfo Id="State" Index="9" />
<ColumnInfo Id="Cargo" Index="10" />
</Columns>
</ListView>
<ListView Id="Client_ListView" DataAccessMode="Server" />
<ListView Id="Client_LookupListView" AllowDelete="False" AllowNew="False" AllowLink="True" DataAccessMode="Server" />
<DetailView Id="Expense_DetailView">
<Items>
<PropertyEditor Id="Cargo" PropertyName="Cargo" IsNewNode="True" />
</Items>
<Layout>
<LayoutGroup Id="Main" RelativeSize="100">
<LayoutGroup Id="SimpleEditors" RelativeSize="100">
<LayoutGroup Id="Expense" RelativeSize="100">
<LayoutItem Id="Amount" RelativeSize="3.048780487804878" />
<LayoutItem Id="ExpenseDate" RelativeSize="2.5609756097560976" />
<LayoutItem Id="Cargo" ViewItem="Cargo" Index="2" RelativeSize="2.5609756097560976" IsNewNode="True" />
<LayoutItem Id="Description" Index="3" RelativeSize="91.82926829268293" />
</LayoutGroup>
</LayoutGroup>
</LayoutGroup>
</Layout>
</DetailView>
<ListView Id="Expense_ListView" DataAccessMode="Server" />
<ListView Id="Expense_LookupListView" DataAccessMode="Server" AllowDelete="False" AllowNew="False" AllowLink="True" />
<ListView Id="Goods_ListView" DataAccessMode="Server">
<Columns>
<ColumnInfo Id="Cargo" Index="-1" OwnerBand="Info" />
<ColumnInfo Id="Oid" OwnerBand="Info" />
<ColumnInfo Id="No" OwnerBand="Info" />
<ColumnInfo Id="Client" OwnerBand="Info" />
<ColumnInfo Id="Name" OwnerBand="Info" />
<ColumnInfo Id="Volume" OwnerBand="Dimensions" />
<ColumnInfo Id="PlaceCount" OwnerBand="Dimensions" />
<ColumnInfo Id="PackageCount" OwnerBand="Dimensions" />
<ColumnInfo Id="PackingType" OwnerBand="Dimensions" />
<ColumnInfo Id="ReceivedAt" OwnerBand="Info" />
<ColumnInfo Id="Price" OwnerBand="Finance" />
<ColumnInfo Id="Height" OwnerBand="Dimensions" />
<ColumnInfo Id="Width" OwnerBand="Dimensions" />
<ColumnInfo Id="Depth" OwnerBand="Dimensions" />
<ColumnInfo Id="TotalPayment" OwnerBand="Finance" />
<ColumnInfo Id="Credit" OwnerBand="Finance" />
<ColumnInfo Id="State" OwnerBand="Info" />
</Columns>
<BandsLayout Enable="True">
<Band Id="Info" Caption="Info" Index="0" IsNewNode="True" />
<Band Id="Dimensions" Caption="Dimensions" Index="2" IsNewNode="True" />
<Band Id="Finance" Caption="Finance" IsNewNode="True" />
</BandsLayout>
</ListView>
<ListView Id="Goods_LookupListView" DataAccessMode="Server" AllowDelete="False" AllowLink="True" AllowNew="False" />
<ListView Id="Goods_Payments_ListView" DataAccessMode="Server" />
<DetailView Id="Payment_DetailView">
<Items>
<PropertyEditor Id="Goods" PropertyName="Goods" IsNewNode="True" />
</Items>
<Layout>
<LayoutGroup Id="Main" RelativeSize="100">
<LayoutGroup Id="SimpleEditors" RelativeSize="100">
<LayoutGroup Id="Payment" RelativeSize="100">
<LayoutItem Id="Amount" RelativeSize="2.0209059233449476" />
<LayoutItem Id="PaymentDate" RelativeSize="1.5331010452961673" />
<LayoutItem Id="Description" RelativeSize="1.5331010452961673" />
<LayoutItem Id="Goods" ViewItem="Goods" Index="3" RelativeSize="1.5331010452961673" IsNewNode="True" />
<LayoutItem Id="Client" Index="4" RelativeSize="93.37979094076655" />
</LayoutGroup>
</LayoutGroup>
</LayoutGroup>
</Layout>
</DetailView>
<ListView Id="Payment_ListView" DataAccessMode="Server" />
<ListView Id="Payment_LookupListView" DataAccessMode="Server" AllowDelete="False" />
<ListView Id="Point_ListView" DataAccessMode="Server" />
<ListView Id="Point_LookupListView" DataAccessMode="Server" />
</Views>
</Application>

View File

@ -0,0 +1,53 @@
using System.ComponentModel;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.BaseImpl.PermissionPolicy;
using DevExpress.ExpressApp.Model;
using DevExpress.ExpressApp.Actions;
using DevExpress.ExpressApp.Editors;
using DevExpress.ExpressApp.Updating;
using DevExpress.ExpressApp.Model.Core;
using DevExpress.ExpressApp.Model.DomainLogics;
using DevExpress.ExpressApp.Model.NodeGenerators;
using DevExpress.Xpo;
using DevExpress.ExpressApp.Xpo;
namespace DurnyklyYol.Module;
// For more typical usage scenarios, be sure to check out https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.ModuleBase.
public sealed class DurnyklyYolModule : ModuleBase {
public DurnyklyYolModule() {
//
// DurnyklyYolModule
//
AdditionalExportedTypes.Add(typeof(OidGenerator));
AdditionalExportedTypes.Add(typeof(DevExpress.Persistent.BaseImpl.ModelDifference));
AdditionalExportedTypes.Add(typeof(DevExpress.Persistent.BaseImpl.ModelDifferenceAspect));
AdditionalExportedTypes.Add(typeof(DevExpress.Persistent.BaseImpl.BaseObject));
AdditionalExportedTypes.Add(typeof(DevExpress.Persistent.BaseImpl.FileData));
AdditionalExportedTypes.Add(typeof(DevExpress.Persistent.BaseImpl.FileAttachmentBase));
RequiredModuleTypes.Add(typeof(DevExpress.ExpressApp.SystemModule.SystemModule));
RequiredModuleTypes.Add(typeof(DevExpress.ExpressApp.Security.SecurityModule));
RequiredModuleTypes.Add(typeof(DevExpress.ExpressApp.Objects.BusinessClassLibraryCustomizationModule));
RequiredModuleTypes.Add(typeof(DevExpress.ExpressApp.ConditionalAppearance.ConditionalAppearanceModule));
RequiredModuleTypes.Add(typeof(DevExpress.ExpressApp.PivotGrid.PivotGridModule));
RequiredModuleTypes.Add(typeof(DevExpress.ExpressApp.ReportsV2.ReportsModuleV2));
RequiredModuleTypes.Add(typeof(DevExpress.ExpressApp.Validation.ValidationModule));
RequiredModuleTypes.Add(typeof(DevExpress.ExpressApp.ViewVariantsModule.ViewVariantsModule));
RequiredModuleTypes.Add(typeof(FileSystemData.FileSystemDataModule));
}
public override IEnumerable<ModuleUpdater> GetModuleUpdaters(IObjectSpace objectSpace, Version versionFromDB) {
ModuleUpdater updater = new DatabaseUpdate.Updater(objectSpace, versionFromDB);
return new ModuleUpdater[] { updater };
}
public override void Setup(XafApplication application) {
base.Setup(application);
// Manage various aspects of the application UI and behavior at the module level.
}
public override void CustomizeTypesInfo(ITypesInfo typesInfo) {
base.CustomizeTypesInfo(typesInfo);
CalculatedPersistentAliasHelper.CustomizeTypesInfo(typesInfo);
}
}

View File

@ -0,0 +1,32 @@
Project Description
This project implements a platform-agnostic Module. UI-independent application
elements can be implemented here (Business Objects, Controllers, etc.). The root project
folder contains the Module.cs(vb) file with the class that inherits ModuleBase.
This class allows you to view and customize Module components:
referenced modules, Controllers and business classes. Additionally, the root folder
contains Application Model difference files (XAFML files) that keep application
settings specific for the current Module. Difference files can be customized in code
or in the Model Editor.
Relevant Documentation
Application Solution Components
https://docs.devexpress.com/eXpressAppFramework/112569
XAF Community Extensions
https://www.devexpress.com/products/net/application_framework/#extensions
Debugging, Unit and Functional Testing
https://docs.devexpress.com/eXpressAppFramework/112572
ModuleBase Class
https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.ModuleBase
Application Model
https://docs.devexpress.com/eXpressAppFramework/112579
Model Editor
https://docs.devexpress.com/eXpressAppFramework/112582

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Application>
<Views Id="Views">
<DetailView Id="Cargo_DetailView">
<Layout Id="Layout">
<LayoutGroup Id="Main">
<LayoutGroup Id="SimpleEditors">
<LayoutGroup Id="Cargo">
<LayoutGroup Id="Cargo_col1">
<LayoutItem Id="No" RelativeSize="16.233766233766232" />
</LayoutGroup>
</LayoutGroup>
</LayoutGroup>
</LayoutGroup>
</Layout>
</DetailView>
<ListView Id="Goods_ListView">
<Columns Id="Columns">
<ColumnInfo Id="Shop" OwnerBand="Info" />
</Columns>
</ListView>
</Views>
</Application>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<Application>
<BOModel Id="BOModel">
<Class Name="DurnyklyYol.Module.BusinessObjects.Client">
<OwnMembers Id="OwnMembers">
<Member Name="PhoneNo" Caption="Telefony" />
</OwnMembers>
</Class>
<Class Name="DurnyklyYol.Module.BusinessObjects.Goods">
<OwnMembers Id="OwnMembers">
<Member Name="Shop" Caption="Dükany" />
</OwnMembers>
</Class>
</BOModel>
<NavigationItems Id="NavigationItems">
<Items Id="Items">
<Item Id="Places">
<Items Id="Items">
<Item Id="Shop_ListView" Caption="Dükanlar" />
</Items>
</Item>
</Items>
</NavigationItems>
</Application>

View File

@ -0,0 +1,192 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Your XAF application</title>
<style>
body {
background: #fff;
color: #505050;
font: 12px 'Segoe UI', tahoma, arial, helvetica, sans-serif;
margin: 20px;
padding: 0;
}
#header {
background: #efefef;
padding: 0;
}
h1 {
font-size: 20px;
font-weight: normal;
margin: 0;
padding: 0 30px;
line-height: 50px;
}
p {
font-size: 20px;
color: #fff;
background: #ff6a00;
padding: 0 30px;
line-height: 50px;
}
#main {
padding: 5px 15px;
}
.section {
width: 18%;
float: left;
min-width : 200px;
margin: 10px 0 0 15px;
}
.section h2 {
font-size: 13px;
text-transform: uppercase;
margin: 0;
border-bottom: 1px solid silver;
padding-bottom: 12px;
margin-bottom: 8px;
}
.section.first {
margin-left: 0;
margin-right : 14px;
width: 10%;
min-width : 330px;
}
.section.first h2 {
font-size: 14px;
text-transform: none;
margin-bottom: 2px;
border: none;
}
.section.first li {
border-top: 1px solid silver;
padding: 8px 0;
}
.section.last {
margin-right: 0;
}
ul {
list-style: none;
padding: 0;
margin: 0;
line-height: 18px;
}
li {
padding: 6px 0;
}
a {
color: #267cb2;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div id="header">
<p>Congratulations! You've created a project</p>
</div>
<div id="main" style="width:100%">
<table style="width:100%">
<tr>
<td style="width:330px; vertical-align:top">
<div class="section first">
<h2>The XAF Solution Wizard has successfully generated the solution according to your settings.</h2>
<ul>
<li>The <b>DurnyklyYol.Module</b> project keeps your platform-agnostic code.
Add persistent objects code to the <b>Business Objects</b> folder of this project and XAF will automatically create a UI to create, read, update and delete these persistent objects.</li>
<li>The <b>DurnyklyYol.Win</b> project is a startup project for the desktop application.</li>
<li>To specify the database used by your application, modify the ConnectionString attribute in the configuration file located in the startup project.</li>
<li>To login, enter the <b>"Admin"</b> user name with empty password.</li>
</ul>
</div>
</td>
<td style="vertical-align:top">
<div class="section">
<h2>1. Design Data Model</h2>
<ul>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112847">Ways to Add a Business Class</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/113586">Define the Logical Data Model and Relationships</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/113525">Display Member of a Business Class</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/113014">Data Types Supported by Built-in Editors</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/117395">PropertyChanged Event in Business Classes</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112600">Business Model Design with XPO</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112788">Supply Initial Data</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112701">Data Annotations in Data Model</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/113583">Customize Business Class Metadata Dynamically</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/116516">Non-Persistent Objects</a></li>
</ul>
</div>
<div class="section">
<h2>2. Customize UI Structure</h2>
<ul>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112569">Application Solution Components</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/113445">Application Personalization</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112579">Application UI Model</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112607">UI Element Overview</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112748">UI Customization</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112843">Design-Time Features</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/113298">Localization</a></li>
</ul>
</div>
<div class="section" style="min-width : 220px">
<h2>3. Implement Custom Behavior</h2>
<ul>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/113708">Data Manipulation and Business Logic</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112623">Controllers and Actions</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112803">Ways to Show a View</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112740">Extend Functionality</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/120092">Access UI Elements and Their Controls</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/113610">Using a Custom Control that is not Integrated by Default</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112572">Debugging and Error Handling</a></li>
</ul>
</div>
<div class="section">
<h2>4. Test and Deploy</h2>
<ul>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112572">Unit and Functional Testing</a></li>
<li><a href="https://www.devexpress.com/kb=T148978">Measure and Improve Performance</a></li>
<li><a href="https://nuget.devexpress.com">Optimize CI/CD Processes with NuGet</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/113033">Redistribution and Deployment</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/113231">Deployment Tutorial</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/113238">Deployment Troubleshooting</a></li>
</ul>
</div>
<div class="section">
<h2>5. Get Support and Learn</h2>
<ul>
<li><a href="https://www.devexpress.com/sc">Search the KB, Examples and Support Tickets</a></li>
<li><a href="https://www.devexpress.com/go/XAF_Community_Consulting_Training.aspx">XAF Community, Consulting and Training</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/113054">Frequently Asked Questions (FAQ)</a></li>
<li><a href="https://docs.devexpress.com/eXpressAppFramework/112682/">Task-Based Help By Categories</a></li>
<li><a href="https://community.devexpress.com/blogs/xaf/">Development Blog</a></li>
<li><a href="https://www.devexpress.com/go/XAF_Roadmap.aspx">Roadmap</a></li>
</ul>
</div>
</td>
</tr>
</table>
</div>
<div id="footer">
<ul><li>If you have questions or need assistance, our <a href="https://supportcenter.devexpress.com/">best-in-class support service</a> is ready to help you.</li></ul>
</div>
</body>
</html>

View File

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System">
<section name="DevExpress.LookAndFeel.Design.AppSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<DevExpress.LookAndFeel.Design.AppSettings>
<setting name="DPIAwarenessMode" serializeAs="String">
<value>System</value>
</setting>
</DevExpress.LookAndFeel.Design.AppSettings>
</applicationSettings>
<appSettings>
<add key="Modules" value="" />
<add key="NewVersionServer" value="" />
<add key="EnableDiagnosticActions" value="False" />
<add key="eXpressAppFrameworkTraceLevel" value="3" />
<add key="Languages" value="tk-TM" />
</appSettings>
<connectionStrings>
</connectionStrings>
</configuration>

View File

@ -0,0 +1,25 @@
Folder Description
The "Controllers" project folder is intended for storing WinForms-specific Controller classes
that can change the default XAF application flow and add new features.
Relevant Documentation
Controllers and Actions
https://docs.devexpress.com/eXpressAppFramework/112623
Implement Custom Controllers
https://docs.devexpress.com/eXpressAppFramework/112621
Define the Scope of Controllers and Actions
https://docs.devexpress.com/eXpressAppFramework/113103
Ways to Show a View
https://docs.devexpress.com/eXpressAppFramework/112803
Ways to Implement Business Logic
https://docs.devexpress.com/eXpressAppFramework/113710
Debugging, Unit and Functional Testing
https://docs.devexpress.com/eXpressAppFramework/112572

View File

@ -0,0 +1,50 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>ExpressApp.ico</ApplicationIcon>
<Deterministic>false</Deterministic>
<AssemblyVersion>1.0.*</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<Configurations>Debug;Release;EasyTest</Configurations>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Using Include="DevExpress.ExpressApp.ListView" Alias="ListView" />
</ItemGroup>
<ItemGroup>
<None Remove="Model.xafml" />
<None Remove="Images\Logo.svg" />
</ItemGroup>
<ItemGroup>
<Content Include="Model.xafml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Images\Logo.svg" />
<EmbeddedResource Include="Images\ExpressAppLogo.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="DevExpress.ExpressApp" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.CodeAnalysis" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.FileAttachment.Win" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.PivotGrid.Win" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.ReportsV2.Win" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Security.Xpo" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Security.Xpo.Extensions.Win" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Validation.Win" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Win" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Win.Design" Version="24.1.4" />
<PackageReference Include="DevExpress.ExpressApp.Xpo" Version="24.1.4" />
<PackageReference Include="DevExpress.Persistent.Base" Version="24.1.4" />
<PackageReference Include="DevExpress.Persistent.BaseImpl.Xpo" Version="24.1.4" />
<PackageReference Include="DevExpress.RichEdit.Export" Version="24.1.4" />
<PackageReference Include="DevExpress.Win.Design" Version="24.1.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DurnyklyYol.Module\DurnyklyYol.Module.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,46 @@
Folder Description
This project folder is intended for storing custom WinForms List Editors,
Property Editors and View Items.
Relevant Documentation
Using a Custom Control that is not Integrated by Default
https://docs.devexpress.com/eXpressAppFramework/113610
Ways to Access UI Elements and Their Controls
https://docs.devexpress.com/eXpressAppFramework/120092
Views
https://docs.devexpress.com/eXpressAppFramework/112611
List Editors
https://docs.devexpress.com/eXpressAppFramework/113189
Implement Custom Property Editors
https://docs.devexpress.com/eXpressAppFramework/113097
View Items
https://docs.devexpress.com/eXpressAppFramework/112612
How to: Implement a Custom WinForms List Editor
https://docs.devexpress.com/eXpressAppFramework/112659
How to: Support a Context Menu for a Custom WinForms List Editor
https://docs.devexpress.com/eXpressAppFramework/112660
How to: Implement a Property Editor (in WinForms Applications)
https://docs.devexpress.com/eXpressAppFramework/112679
How to: Implement a Property Editor for Specific Data Management (in WinForms Applications)
https://docs.devexpress.com/eXpressAppFramework/113101
How to: Extend Built-in Property Editor's Functionality
https://docs.devexpress.com/eXpressAppFramework/113104
How to: Implement a View Item
https://docs.devexpress.com/eXpressAppFramework/112641
Debugging, Unit and Functional Testing
https://docs.devexpress.com/eXpressAppFramework/112572

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -0,0 +1,16 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 70 20" style="enable-background:new 0 0 70 20;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FF7200;}
</style>
<path class="st0" d="M5.2,20H0V0h5.2v2.2H2.7v15.6h2.5V20z M9.3,18.3V1.9h3v13.7h4.1v2.7H9.3z M31.7,10.1c0,2.7-0.5,4.8-1.5,6.2
c-1,1.5-2.4,2.2-4.3,2.2c-1.9,0-3.3-0.7-4.3-2.2c-1-1.5-1.5-3.5-1.5-6.3c0-2.7,0.5-4.8,1.5-6.2c1-1.4,2.4-2.2,4.3-2.2
c1.9,0,3.3,0.7,4.3,2.2C31.2,5.3,31.7,7.4,31.7,10.1z M23.2,10.1c0,1.9,0.2,3.3,0.7,4.3c0.5,1,1.1,1.5,2,1.5c1.8,0,2.7-1.9,2.7-5.7
s-0.9-5.7-2.7-5.7c-0.9,0-1.6,0.5-2.1,1.5C23.4,6.8,23.2,8.2,23.2,10.1z M41.1,9.2H46v8.4c-1.4,0.6-2.9,0.9-4.4,0.9
c-1.9,0-3.3-0.7-4.3-2.2c-1-1.4-1.5-3.5-1.5-6.3c0-2.6,0.6-4.7,1.7-6.2s2.8-2.2,4.8-2.2c1.3,0,2.5,0.3,3.7,1l-0.9,2.5
c-0.9-0.5-1.8-0.8-2.5-0.8c-1.1,0-2,0.5-2.7,1.6c-0.7,1-1,2.4-1,4.2c0,1.8,0.2,3.2,0.7,4.2c0.5,1,1.2,1.5,2.1,1.5
c0.5,0,1-0.1,1.5-0.2v-3.8h-2V9.2z M61.8,10.1c0,2.7-0.5,4.8-1.5,6.2s-2.4,2.2-4.3,2.2c-1.9,0-3.3-0.7-4.3-2.2
c-1-1.5-1.5-3.5-1.5-6.3c0-2.7,0.5-4.8,1.5-6.2c1-1.4,2.4-2.2,4.3-2.2c1.9,0,3.3,0.7,4.3,2.2C61.3,5.3,61.8,7.4,61.8,10.1z
M53.3,10.1c0,1.9,0.2,3.3,0.7,4.3s1.1,1.5,2,1.5c1.8,0,2.7-1.9,2.7-5.7s-0.9-5.7-2.7-5.7c-0.9,0-1.6,0.5-2.1,1.5
S53.3,8.2,53.3,10.1z M64.8,17.8h2.5V2.2h-2.5V0H70v20h-5.2V17.8z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,12 @@
Folder Description
The "Images" project folder is intended for storing custom image files.
Relevant Documentation
Add and Override Images
https://docs.devexpress.com/eXpressAppFramework/112792
Assign a Custom Image
https://docs.devexpress.com/eXpressAppFramework/112744

View File

@ -0,0 +1,4 @@
<Application Logo="ExpressAppLogo">
<Options UIType="TabbedMDI" FormStyle="Ribbon" />
<NavigationItems NavigationStyle="Accordion" DefaultChildItemsDisplayStyle="List"/>
</Application>

View File

@ -0,0 +1,51 @@
using System.Configuration;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.ApplicationBuilder;
using DevExpress.ExpressApp.Win.ApplicationBuilder;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.Win;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.XtraEditors;
using System.Net;
using System.Net.Http.Json;
using System.Net.Http.Headers;
using System.Net.Http;
using DevExpress.ExpressApp.Security.ClientServer;
using DevExpress.Persistent.BaseImpl.PermissionPolicy;
namespace DurnyklyYol.Win;
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static int Main(string[] args) {
DevExpress.ExpressApp.FrameworkSettings.DefaultSettingsCompatibilityMode = DevExpress.ExpressApp.FrameworkSettingsCompatibilityMode.Latest;
DevExpress.ExpressApp.Security.SecurityStrategy.AutoAssociationReferencePropertyMode = DevExpress.ExpressApp.Security.ReferenceWithoutAssociationPermissionsMode.AllMembers;
#if EASYTEST
DevExpress.ExpressApp.Win.EasyTest.EasyTestRemotingRegistration.Register();
#endif
WindowsFormsSettings.LoadApplicationSettings();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
DevExpress.Utils.ToolTipController.DefaultController.ToolTipType = DevExpress.Utils.ToolTipType.SuperTip;
if(Tracing.GetFileLocationFromSettings() == DevExpress.Persistent.Base.FileLocation.CurrentUserApplicationDataFolder) {
Tracing.LocalUserAppDataPath = Application.LocalUserAppDataPath;
}
Tracing.Initialize();
var winApplication = ApplicationBuilder.BuildApplication();
try {
winApplication.Setup();
winApplication.Start();
}
catch(Exception e) {
winApplication.StopSplash();
winApplication.HandleException(e);
}
return 0;
}
}

View File

@ -0,0 +1,33 @@
Project Description
This project implements a WinForms application. The root project folder
contains the WinApplication.cs file with the class that inherits WinApplication.
This class allows you to view and customize Module components:
referenced modules, Controllers and business classes. Additionally, the root folder
contains Application Model difference files (XAFML files) that keep application
settings specific for the current Module. Difference files can be customized in code
or in the Model Editor.
Relevant Documentation
Application Solution Components
https://docs.devexpress.com/eXpressAppFramework/112569
XAF Community Extensions
https://www.devexpress.com/products/net/application_framework/#extensions
Debugging, Unit and Functional Testing
https://docs.devexpress.com/eXpressAppFramework/112572
WinApplication Class
https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.Win.WinApplication
XafApplication Class
https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.XafApplication
Application Model
https://docs.devexpress.com/eXpressAppFramework/112579
Model Editor
https://docs.devexpress.com/eXpressAppFramework/112582

View File

@ -0,0 +1,77 @@
using System.Configuration;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.ApplicationBuilder;
using DevExpress.ExpressApp.Win.ApplicationBuilder;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.Win;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.XtraEditors;
using System.Net;
using System.Net.Http.Json;
using System.Net.Http.Headers;
using System.Net.Http;
using DevExpress.ExpressApp.Security.ClientServer;
using DevExpress.Persistent.BaseImpl.PermissionPolicy;
using DevExpress.ExpressApp.Design;
namespace DurnyklyYol.Win;
public class ApplicationBuilder : IDesignTimeApplicationFactory {
public static WinApplication BuildApplication() {
var builder = WinApplication.CreateBuilder();
// Register custom services for Dependency Injection. For more information, refer to the following topic: https://docs.devexpress.com/eXpressAppFramework/404430/
// builder.Services.AddScoped<CustomService>();
// Register 3rd-party IoC containers (like Autofac, Dryloc, etc.)
// builder.UseServiceProviderFactory(new DryIocServiceProviderFactory());
// builder.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.UseApplication<DurnyklyYolWindowsFormsApplication>();
builder.Modules
.AddConditionalAppearance()
.AddFileAttachments()
.AddPivotGrid()
.AddReports(options => {
options.EnableInplaceReports = true;
options.ReportDataType = typeof(DevExpress.Persistent.BaseImpl.ReportDataV2);
options.ReportStoreMode = DevExpress.ExpressApp.ReportsV2.ReportStoreModes.XML;
})
.AddValidation(options => {
options.AllowValidationDetailsAccess = false;
})
.AddViewVariants()
.Add<DurnyklyYol.Module.DurnyklyYolModule>()
.Add<DurnyklyYolWinModule>();
builder.ObjectSpaceProviders
.AddNonPersistent();
builder.Security
.UseMiddleTierMode(options => {
#if DEBUG
options.WaitForMiddleTierServerReady();
#endif
options.BaseAddress = new Uri("http://localhost:5000/");
options.Events.OnHttpClientCreated = client => client.DefaultRequestHeaders.Add("Accept", "application/json");
options.Events.OnCustomAuthenticate = (sender, security, args) => {
args.Handled = true;
HttpResponseMessage msg = args.HttpClient.PostAsJsonAsync("api/Authentication/Authenticate", (AuthenticationStandardLogonParameters)args.LogonParameters).GetAwaiter().GetResult();
string token = (string)msg.Content.ReadFromJsonAsync(typeof(string)).GetAwaiter().GetResult();
if(msg.StatusCode == HttpStatusCode.Unauthorized) {
XafExceptions.Authentication.ThrowAuthenticationFailedFromResponse(token);
}
msg.EnsureSuccessStatusCode();
args.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
};
})
.AddPasswordAuthentication();
builder.AddBuildStep(application => {
});
var winApplication = builder.Build();
return winApplication;
}
XafApplication IDesignTimeApplicationFactory.Create() {
DevExpress.ExpressApp.Security.ClientServer.MiddleTierClientSecurity.DesignModeUserType = typeof(DurnyklyYol.Module.BusinessObjects.ApplicationUser);
DevExpress.ExpressApp.Security.ClientServer.MiddleTierClientSecurity.DesignModeRoleType = typeof(DevExpress.Persistent.BaseImpl.PermissionPolicy.PermissionPolicyRole);
return BuildApplication();
}
}

Some files were not shown because too many files have changed in this diff Show More