...
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Blazor.PersianDatePicker" Version="2.1.0" />
|
||||||
<PackageReference Include="Melipayamak.RestClient" Version="1.0.0" />
|
<PackageReference Include="Melipayamak.RestClient" Version="1.0.0" />
|
||||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.0" />
|
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||||
@@ -34,7 +35,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Service">
|
<Reference Include="Service">
|
||||||
<HintPath>..\..\..\LocalGit\TaxPayerTools\Service\bin\Debug\Service.dll</HintPath>
|
<HintPath>..\..\Dlls\Service.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@@ -38,6 +38,13 @@ namespace Back.Controllers
|
|||||||
[HttpPost("Add")]
|
[HttpPost("Add")]
|
||||||
public async Task<ActionResult<int>> Add([FromBody] NUInvoiceDTO item)
|
public async Task<ActionResult<int>> Add([FromBody] NUInvoiceDTO item)
|
||||||
{
|
{
|
||||||
|
if(string.IsNullOrEmpty(item.InvoiceDate))
|
||||||
|
item.InvoiceDate = DateTime.Now.ConvertMiladiToShamsi();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(item.InvoicIssueDate))
|
||||||
|
item.InvoicIssueDate = DateTime.Now.ConvertMiladiToShamsi();
|
||||||
|
|
||||||
|
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
return BadRequest(item);
|
return BadRequest(item);
|
||||||
|
|
||||||
@@ -113,11 +120,20 @@ namespace Back.Controllers
|
|||||||
|
|
||||||
|
|
||||||
//-----change invoice
|
//-----change invoice
|
||||||
|
if (!string.IsNullOrEmpty(item.Title))
|
||||||
invoice.Title = item.Title;
|
invoice.Title = item.Title;
|
||||||
|
|
||||||
invoice.PatternID = item.PatternID;
|
invoice.PatternID = item.PatternID;
|
||||||
|
|
||||||
|
if(item.CustomerID > 0)
|
||||||
invoice.CustomerID = item.CustomerID;
|
invoice.CustomerID = item.CustomerID;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(item.InvoicIssueDate))
|
||||||
invoice.InvoicIssueDate = item.InvoicIssueDate;
|
invoice.InvoicIssueDate = item.InvoicIssueDate;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(item.InvoiceDate))
|
||||||
invoice.InvoiceDate = item.InvoiceDate;
|
invoice.InvoiceDate = item.InvoiceDate;
|
||||||
|
|
||||||
invoice.Des = item.Des;
|
invoice.Des = item.Des;
|
||||||
invoice.LastChangeUserID = Convert.ToInt32(UserID);
|
invoice.LastChangeUserID = Convert.ToInt32(UserID);
|
||||||
|
|
||||||
@@ -341,5 +357,10 @@ namespace Back.Controllers
|
|||||||
return NoContent();
|
return NoContent();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
[HttpGet("GetPatterns")]
|
||||||
|
public async Task<ActionResult<List<IdName<int>>>> GetPatterns()
|
||||||
|
{
|
||||||
|
return Ok(await _servTaxPayer.GetPatterns());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,9 +8,11 @@ namespace Back.Services
|
|||||||
public class servTaxPayer
|
public class servTaxPayer
|
||||||
{
|
{
|
||||||
private readonly IAsyncRepository<SentTax> _repoSentTax;
|
private readonly IAsyncRepository<SentTax> _repoSentTax;
|
||||||
public servTaxPayer(IAsyncRepository<SentTax> repoSentTax)
|
private readonly IAsyncRepository<Pattern> _repoPattern;
|
||||||
|
public servTaxPayer(IAsyncRepository<SentTax> repoSentTax, IAsyncRepository<Pattern> repoPattern)
|
||||||
{
|
{
|
||||||
_repoSentTax = repoSentTax;
|
_repoSentTax = repoSentTax;
|
||||||
|
_repoPattern = repoPattern;
|
||||||
}
|
}
|
||||||
public async Task<bool> ExistSuccessfulorSendorpendingInvoiceinCompanyID(int CompanyID)
|
public async Task<bool> ExistSuccessfulorSendorpendingInvoiceinCompanyID(int CompanyID)
|
||||||
{
|
{
|
||||||
@@ -27,6 +29,10 @@ namespace Back.Services
|
|||||||
&& (w.SentStatus == SentStatus.Successful || w.SentStatus == SentStatus.Send || w.SentStatus == SentStatus.pending)
|
&& (w.SentStatus == SentStatus.Successful || w.SentStatus == SentStatus.Send || w.SentStatus == SentStatus.pending)
|
||||||
&& w.invoice.CompanyID != CompanyID).AnyAsync();
|
&& w.invoice.CompanyID != CompanyID).AnyAsync();
|
||||||
}
|
}
|
||||||
|
public async Task<List<IdName<int>>> GetPatterns()
|
||||||
|
{
|
||||||
|
return await _repoPattern.Get(w=>w.Status).Select(s => new IdName<int> { ID = s.ID, Title = s.Title }).ToListAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
48
Blazor.PersianDatePicker/Blazor.PersianDatePicker.csproj
Normal file
48
Blazor.PersianDatePicker/Blazor.PersianDatePicker.csproj
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>net5.0</TargetFrameworks>
|
||||||
|
<Version>3.3.0</Version>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
<NoWarn>$(NoWarn);NU1701;1702;1591;NU1602;CS8609;CS8610;CS8619;CS8632</NoWarn>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<Authors>Farshad Davoudi</Authors>
|
||||||
|
<Title>Blazor.PersianDatePicker</Title>
|
||||||
|
<Company>Bit</Company>
|
||||||
|
<Description>
|
||||||
|
A free Jalali (Persian) and Gregorian (Miladi) dual datepicker library for Blazor applications
|
||||||
|
</Description>
|
||||||
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
|
<!-- Add README.md to nuget package -->
|
||||||
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
|
<RepositoryURL>https://github.com/farshaddavoudi/Blazor.PersianDatePicker</RepositoryURL>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||||
|
<DebugType>portable</DebugType>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb;.xml</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||||
|
<EmbedAllSources>True</EmbedAllSources>
|
||||||
|
<DebugType>portable</DebugType>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<SupportedPlatform Include="browser" />
|
||||||
|
<!-- Add README.md to nuget package -->
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Delegate.SassBuilder" Version="1.4.0" />
|
||||||
|
<PackageReference Include="SourceLink.Embed.AllSourceFiles" Version="2.8.3" PrivateAssets="all" />
|
||||||
|
<PackageReference Include="SourceLink.Copy.PdbFiles" Version="2.8.3" PrivateAssets="All" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
10
Blazor.PersianDatePicker/Enums/Align.cs
Normal file
10
Blazor.PersianDatePicker/Enums/Align.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// ReSharper disable CheckNamespace
|
||||||
|
|
||||||
|
namespace Blazor.PersianDatePicker
|
||||||
|
{
|
||||||
|
public enum Align
|
||||||
|
{
|
||||||
|
Right,
|
||||||
|
Left
|
||||||
|
}
|
||||||
|
}
|
27
Blazor.PersianDatePicker/Enums/Calendar.cs
Normal file
27
Blazor.PersianDatePicker/Enums/Calendar.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// ReSharper disable once CheckNamespace
|
||||||
|
|
||||||
|
namespace Blazor.PersianDatePicker
|
||||||
|
{
|
||||||
|
public enum Calendar
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Both Jalali (Persian) and Miladi (Gregorian) calendars, with default set to Jalali
|
||||||
|
/// </summary>
|
||||||
|
DualModeJalaliDefault,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Both Jalali (Persian) and Miladi (Gregorian) calendars, with default set to Miladi
|
||||||
|
/// </summary>
|
||||||
|
DualModeMiladiDefault,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Only Jalali (Persian) calendar
|
||||||
|
/// </summary>
|
||||||
|
SingleModeJalali,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Only Miladi (Gregorian) calendar
|
||||||
|
/// </summary>
|
||||||
|
SingleModeMiladi
|
||||||
|
}
|
||||||
|
}
|
48
Blazor.PersianDatePicker/Enums/DateFormat.cs
Normal file
48
Blazor.PersianDatePicker/Enums/DateFormat.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
// ReSharper disable once CheckNamespace
|
||||||
|
|
||||||
|
namespace Blazor.PersianDatePicker
|
||||||
|
{
|
||||||
|
public enum DateFormat
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// e.g. 1400/01/01
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "YYYY/MM/DD")]
|
||||||
|
yyyy_slash_MM_slash_dd,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// e.g. 1400-01-01
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "YYYY-MM-DD")]
|
||||||
|
yyyy_dash_MM_dash_dd
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DateFormatExtensions
|
||||||
|
{
|
||||||
|
public static string GetCSharpFormat(this DateFormat format)
|
||||||
|
{
|
||||||
|
if (format == DateFormat.yyyy_slash_MM_slash_dd)
|
||||||
|
return "yyyy/MM/dd";
|
||||||
|
|
||||||
|
if (format == DateFormat.yyyy_dash_MM_dash_dd)
|
||||||
|
return "yyyy-MM-dd";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetSeparator(this DateFormat format)
|
||||||
|
{
|
||||||
|
if (format == DateFormat.yyyy_slash_MM_slash_dd)
|
||||||
|
return "/";
|
||||||
|
|
||||||
|
if (format == DateFormat.yyyy_dash_MM_dash_dd)
|
||||||
|
return "-";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
22
Blazor.PersianDatePicker/Enums/DigitType.cs
Normal file
22
Blazor.PersianDatePicker/Enums/DigitType.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// ReSharper disable CheckNamespace
|
||||||
|
|
||||||
|
namespace Blazor.PersianDatePicker
|
||||||
|
{
|
||||||
|
public enum DigitType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// For dual calendar mode, will change based on current calendar
|
||||||
|
/// </summary>
|
||||||
|
BasedOnCalendar,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// e.g. ۱۴۰۰/۰۱/۱۱
|
||||||
|
/// </summary>
|
||||||
|
Persian,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// e.g. 1400/01/11
|
||||||
|
/// </summary>
|
||||||
|
English
|
||||||
|
}
|
||||||
|
}
|
11
Blazor.PersianDatePicker/Enums/IconPosition.cs
Normal file
11
Blazor.PersianDatePicker/Enums/IconPosition.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// ReSharper disable CheckNamespace
|
||||||
|
|
||||||
|
namespace Blazor.PersianDatePicker
|
||||||
|
{
|
||||||
|
public enum IconPosition
|
||||||
|
{
|
||||||
|
BasedOnAlign,
|
||||||
|
Right,
|
||||||
|
Left
|
||||||
|
}
|
||||||
|
}
|
23
Blazor.PersianDatePicker/Enums/PickerTheme.cs
Normal file
23
Blazor.PersianDatePicker/Enums/PickerTheme.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
// ReSharper disable CheckNamespace
|
||||||
|
|
||||||
|
namespace Blazor.PersianDatePicker
|
||||||
|
{
|
||||||
|
public enum PickerTheme
|
||||||
|
{
|
||||||
|
[Display(Name = "default-theme")]
|
||||||
|
Default,
|
||||||
|
|
||||||
|
[Display(Name = "dark-theme")]
|
||||||
|
Dark,
|
||||||
|
|
||||||
|
[Display(Name = "blue-theme")]
|
||||||
|
Blue,
|
||||||
|
|
||||||
|
[Display(Name = "cheerup-theme")]
|
||||||
|
Cheerup,
|
||||||
|
|
||||||
|
[Display(Name = "redblack-theme")]
|
||||||
|
RedBlack
|
||||||
|
}
|
||||||
|
}
|
24
Blazor.PersianDatePicker/Extensions/EnumExtensions.cs
Normal file
24
Blazor.PersianDatePicker/Extensions/EnumExtensions.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Blazor.PersianDatePicker.Extensions
|
||||||
|
{
|
||||||
|
public static class EnumExtensions
|
||||||
|
{
|
||||||
|
public static string? ToEnumDisplayName(this Enum value, bool showEnumStringIfNoDisplayName = true)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
|
||||||
|
var displayName = value.GetType()
|
||||||
|
.GetMember(value.ToString())
|
||||||
|
.First()
|
||||||
|
?.GetCustomAttributes<DisplayAttribute>()
|
||||||
|
.FirstOrDefault()
|
||||||
|
?.GetName();
|
||||||
|
return displayName ?? (showEnumStringIfNoDisplayName ? value.ToString() : null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
Blazor.PersianDatePicker/Extensions/StringExtensions.cs
Normal file
44
Blazor.PersianDatePicker/Extensions/StringExtensions.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
namespace Blazor.PersianDatePicker.Extensions
|
||||||
|
{
|
||||||
|
public static class StringExtensions
|
||||||
|
{
|
||||||
|
public static string EnglishToPersianDigits(this string str)
|
||||||
|
{
|
||||||
|
return str.Replace("0", "۰")
|
||||||
|
.Replace("1", "۱")
|
||||||
|
.Replace("2", "۲")
|
||||||
|
.Replace("3", "۳")
|
||||||
|
.Replace("4", "۴")
|
||||||
|
.Replace("5", "۵")
|
||||||
|
.Replace("6", "۶")
|
||||||
|
.Replace("7", "۷")
|
||||||
|
.Replace("8", "۸")
|
||||||
|
.Replace("9", "۹");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string PersianToEnglishDigits(this string str)
|
||||||
|
{
|
||||||
|
return str.Replace("۰", "0")
|
||||||
|
.Replace("۱", "1")
|
||||||
|
.Replace("۲", "2")
|
||||||
|
.Replace("۳", "3")
|
||||||
|
.Replace("۴", "4")
|
||||||
|
.Replace("۵", "5")
|
||||||
|
.Replace("۶", "6")
|
||||||
|
.Replace("۷", "7")
|
||||||
|
.Replace("۸", "8")
|
||||||
|
.Replace("۹", "9")
|
||||||
|
//iphone numeric
|
||||||
|
.Replace("٠", "0")
|
||||||
|
.Replace("١", "1")
|
||||||
|
.Replace("٢", "2")
|
||||||
|
.Replace("٣", "3")
|
||||||
|
.Replace("٤", "4")
|
||||||
|
.Replace("٥", "5")
|
||||||
|
.Replace("٦", "6")
|
||||||
|
.Replace("٧", "7")
|
||||||
|
.Replace("٨", "8")
|
||||||
|
.Replace("٩", "9");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
402
Blazor.PersianDatePicker/InputPersianDatePicker.razor
Normal file
402
Blazor.PersianDatePicker/InputPersianDatePicker.razor
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
@using System.ComponentModel.DataAnnotations
|
||||||
|
@if (Visible)
|
||||||
|
{
|
||||||
|
<div class="datepicker_wrapp" style="@Style">
|
||||||
|
<input id="@Id"
|
||||||
|
name="@Name"
|
||||||
|
readonly="@ReadOnly"
|
||||||
|
disabled="@Disabled"
|
||||||
|
class="@_internalCssClass @_iconCssClass @CssClass"
|
||||||
|
placeholder="@Placeholder"
|
||||||
|
autocomplete="off"
|
||||||
|
maxlength="10"
|
||||||
|
value="@Value"
|
||||||
|
init-value="@Value"
|
||||||
|
@onchange="@Change" />
|
||||||
|
<span class="@_clearBtnCssClass" @onclick="@Clear">×</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
private string? _internalCssClass;
|
||||||
|
|
||||||
|
private string? _iconCssClass;
|
||||||
|
|
||||||
|
private string? _clearBtnCssClass;
|
||||||
|
|
||||||
|
public FieldIdentifier FieldIdentifier { get; private set; }
|
||||||
|
|
||||||
|
private string? _value;
|
||||||
|
|
||||||
|
private bool _isJalaliCurrentCalendarType;
|
||||||
|
|
||||||
|
[CascadingParameter]
|
||||||
|
public EditContext? EditContext { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public virtual string? Value
|
||||||
|
{
|
||||||
|
get => _value;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!EqualityComparer<string>.Default.Equals(value, _value))
|
||||||
|
{
|
||||||
|
_value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<string> ValueChanged { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Html input element id attribute (Required)
|
||||||
|
/// </summary>
|
||||||
|
[Parameter, Required]
|
||||||
|
public string? Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Html input element name attribute (Optional)
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Control visibility of input
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public bool Visible { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disabled make input disabled. Meaning only showing value and picker popup won't open
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public bool Disabled { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Picker align relative to input
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public Align PickerAlign { get; set; } = Align.Right;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Show calendar icon on input
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public bool ShowCalendarIcon { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calendar icon position relative to input
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public IconPosition CalendarIconPosition { get; set; } = IconPosition.BasedOnAlign;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Can be used in changing vertical position of picker popup relative to input
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public double PickerOffsetTopPositionInPixels { get; set; } = 2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initial value for input set on today
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public bool InitialValueSetOnToday { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calendar type for date picker including Dual, Single, etc
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public Calendar CalendarType { get; set; } = Calendar.DualModeJalaliDefault;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Control the digit type showing in input after selecting by picker
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public DigitType DigitType { get; set; } = DigitType.BasedOnCalendar;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Format of date to show in input after selecting by picker
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public DateFormat DateFormat { get; set; } = DateFormat.yyyy_slash_MM_slash_dd;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prevent user select date before today
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public bool MinDateSetOnToday { get; set; } = true;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string? Placeholder { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set datepicker readonly
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public bool ReadOnly { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// CSS class for input element
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string? CssClass { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Inline styles for input element
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string? Style { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Choose a theme for changing look and feel of picker
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public PickerTheme Theme { get; set; } = PickerTheme.Default;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public Expression<Func<string>>? ValueExpression { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<string> OnChange { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback OnClear { get; set; }
|
||||||
|
|
||||||
|
[Inject] private IJSRuntime? JsRuntime { get; set; }
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(Id))
|
||||||
|
Id = "id" + new Random().Next(1000, 9999);
|
||||||
|
|
||||||
|
if (CalendarType == Calendar.DualModeJalaliDefault || CalendarType == Calendar.SingleModeJalali)
|
||||||
|
_isJalaliCurrentCalendarType = true;
|
||||||
|
|
||||||
|
else
|
||||||
|
_isJalaliCurrentCalendarType = false;
|
||||||
|
|
||||||
|
if (!ShowCalendarIcon)
|
||||||
|
{
|
||||||
|
_iconCssClass = "";
|
||||||
|
_clearBtnCssClass = "clear-btn right";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (CalendarIconPosition == IconPosition.Left)
|
||||||
|
{
|
||||||
|
_iconCssClass = "persian-datepicker-left-icon";
|
||||||
|
_clearBtnCssClass = "clear-btn right";
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (CalendarIconPosition == IconPosition.Right)
|
||||||
|
{
|
||||||
|
_iconCssClass = "persian-datepicker-right-icon";
|
||||||
|
_clearBtnCssClass = "clear-btn left";
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (PickerAlign == Align.Right)
|
||||||
|
{
|
||||||
|
_iconCssClass = "persian-datepicker-left-icon";
|
||||||
|
_clearBtnCssClass = "clear-btn right";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_iconCssClass = "persian-datepicker-right-icon";
|
||||||
|
_clearBtnCssClass = "clear-btn left";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InitialValueSetOnToday)
|
||||||
|
{
|
||||||
|
var dt = DateTime.Now;
|
||||||
|
|
||||||
|
_value = _isJalaliCurrentCalendarType
|
||||||
|
? GetPersianDateFromGregorianDate(dt)
|
||||||
|
: dt.ToString(DateFormat.GetCSharpFormat());
|
||||||
|
|
||||||
|
ModifyValueDigit();
|
||||||
|
|
||||||
|
await OnValueChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
_internalCssClass = Disabled ? "datepicker-disabled" : "blazor-datepicker";
|
||||||
|
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Task SetParametersAsync(ParameterView parameters)
|
||||||
|
{
|
||||||
|
var result = base.SetParametersAsync(parameters);
|
||||||
|
|
||||||
|
if (EditContext != null && ValueExpression != null && FieldIdentifier.Model != EditContext.Model)
|
||||||
|
{
|
||||||
|
FieldIdentifier = FieldIdentifier.Create(ValueExpression);
|
||||||
|
EditContext.OnValidationStateChanged += ValidationStateChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ValidationStateChanged(object? sender, ValidationStateChangedEventArgs e)
|
||||||
|
{
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (firstRender)
|
||||||
|
{
|
||||||
|
var calendarType = CalendarType == Calendar.SingleModeJalali || CalendarType == Calendar.DualModeJalaliDefault
|
||||||
|
? "persian"
|
||||||
|
: "gregorian";
|
||||||
|
|
||||||
|
bool enableSwitchCalendar = CalendarType == Calendar.DualModeJalaliDefault || CalendarType == Calendar.DualModeMiladiDefault;
|
||||||
|
|
||||||
|
bool? hasExplicitDigitType = DigitType != DigitType.BasedOnCalendar;
|
||||||
|
|
||||||
|
string digitType = "float";
|
||||||
|
|
||||||
|
if (DigitType == DigitType.Persian)
|
||||||
|
digitType = "fa";
|
||||||
|
|
||||||
|
else if (DigitType == DigitType.English)
|
||||||
|
digitType = "en";
|
||||||
|
|
||||||
|
var minDate = MinDateSetOnToday ? "today" : null;
|
||||||
|
|
||||||
|
await JsRuntime!.InvokeVoidAsync("blazorReady",
|
||||||
|
DotNetObjectReference.Create(this),
|
||||||
|
Id!,
|
||||||
|
calendarType,
|
||||||
|
enableSwitchCalendar,
|
||||||
|
hasExplicitDigitType,
|
||||||
|
digitType,
|
||||||
|
InitialValueSetOnToday,
|
||||||
|
DateFormat.ToEnumDisplayName()!,
|
||||||
|
minDate ?? string.Empty,
|
||||||
|
PickerAlign.ToString().ToLower(),
|
||||||
|
PickerOffsetTopPositionInPixels,
|
||||||
|
Theme.ToEnumDisplayName()!);
|
||||||
|
|
||||||
|
await base.OnAfterRenderAsync(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
await base.OnAfterRenderAsync(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async Task Change(ChangeEventArgs args)
|
||||||
|
{
|
||||||
|
Value = $"{args.Value}";
|
||||||
|
|
||||||
|
await ValueChanged.InvokeAsync(Value);
|
||||||
|
|
||||||
|
EditContext?.NotifyFieldChanged(FieldIdentifier);
|
||||||
|
|
||||||
|
await OnChange.InvokeAsync(Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[JSInvokable]
|
||||||
|
public async Task SetDate(long? timestamp, string elementId, bool switchingCalendar = false)
|
||||||
|
{
|
||||||
|
if (elementId != Id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (timestamp != null)
|
||||||
|
{
|
||||||
|
var dt = new DateTime(1970, 1, 1, 0, 0, 0, 0)
|
||||||
|
.AddSeconds(Math.Round((long)timestamp / 1000d)).ToLocalTime();
|
||||||
|
|
||||||
|
_value = _isJalaliCurrentCalendarType
|
||||||
|
? GetPersianDateFromGregorianDate(dt)
|
||||||
|
: dt.ToString(DateFormat.GetCSharpFormat());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switchingCalendar)
|
||||||
|
{
|
||||||
|
_isJalaliCurrentCalendarType = !_isJalaliCurrentCalendarType;
|
||||||
|
|
||||||
|
if (_isJalaliCurrentCalendarType)
|
||||||
|
{
|
||||||
|
// Change from en to fa: 2021/04/03 => 1400/05/02
|
||||||
|
var dt = Convert.ToDateTime(_value);
|
||||||
|
|
||||||
|
_value = GetPersianDateFromGregorianDate(dt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Change from fa to en: 1400/05/05 => 2021/01/05
|
||||||
|
// Convert to Miladi
|
||||||
|
if (_value != null)
|
||||||
|
{
|
||||||
|
DateTime dt = DateTime.Parse(_value, new CultureInfo("fa-IR"));
|
||||||
|
|
||||||
|
// Get Date
|
||||||
|
_value = dt.ToString(DateFormat.GetCSharpFormat());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ModifyValueDigit();
|
||||||
|
|
||||||
|
await OnValueChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
[JSInvokable]
|
||||||
|
public async Task SetToday(string elementId)
|
||||||
|
{
|
||||||
|
var dt = DateTime.Today;
|
||||||
|
|
||||||
|
_value = _isJalaliCurrentCalendarType
|
||||||
|
? GetPersianDateFromGregorianDate(dt)
|
||||||
|
: dt.ToString(DateFormat.GetCSharpFormat());
|
||||||
|
|
||||||
|
ModifyValueDigit();
|
||||||
|
|
||||||
|
await OnValueChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ModifyValueDigit()
|
||||||
|
{
|
||||||
|
if (DigitType == DigitType.Persian)
|
||||||
|
_value = _value?.EnglishToPersianDigits();
|
||||||
|
|
||||||
|
else if (DigitType == DigitType.English)
|
||||||
|
_value = _value?.PersianToEnglishDigits();
|
||||||
|
|
||||||
|
else if (DigitType == DigitType.BasedOnCalendar)
|
||||||
|
_value = _isJalaliCurrentCalendarType ? _value?.EnglishToPersianDigits() : _value?.PersianToEnglishDigits();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnValueChanged()
|
||||||
|
{
|
||||||
|
await ValueChanged.InvokeAsync(_value);
|
||||||
|
|
||||||
|
EditContext?.NotifyFieldChanged(FieldIdentifier);
|
||||||
|
|
||||||
|
await OnChange.InvokeAsync(Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetPersianDateFromGregorianDate(DateTime dt)
|
||||||
|
{
|
||||||
|
PersianCalendar pc = new PersianCalendar();
|
||||||
|
|
||||||
|
return $"{pc.GetYear(dt):D2}{DateFormat.GetSeparator()}{pc.GetMonth(dt):D2}{DateFormat.GetSeparator()}{pc.GetDayOfMonth(dt):D2}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Clear()
|
||||||
|
{
|
||||||
|
await ValueChanged.InvokeAsync(string.Empty);
|
||||||
|
|
||||||
|
EditContext?.NotifyFieldChanged(FieldIdentifier);
|
||||||
|
|
||||||
|
await OnClear.InvokeAsync();
|
||||||
|
}
|
||||||
|
}
|
7
Blazor.PersianDatePicker/_Imports.razor
Normal file
7
Blazor.PersianDatePicker/_Imports.razor
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@using Microsoft.AspNetCore.Components.Web
|
||||||
|
@using Microsoft.JSInterop
|
||||||
|
@using Microsoft.AspNetCore.Components.Forms
|
||||||
|
@using System.Linq.Expressions
|
||||||
|
@using System.Globalization
|
||||||
|
@using Blazor.PersianDatePicker.Extensions
|
||||||
|
|
BIN
Blazor.PersianDatePicker/wwwroot/calendar_icon.png
Normal file
BIN
Blazor.PersianDatePicker/wwwroot/calendar_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 578 B |
1
Blazor.PersianDatePicker/wwwroot/datepicker.css
Normal file
1
Blazor.PersianDatePicker/wwwroot/datepicker.css
Normal file
File diff suppressed because one or more lines are too long
3966
Blazor.PersianDatePicker/wwwroot/datepicker.min.js
vendored
Normal file
3966
Blazor.PersianDatePicker/wwwroot/datepicker.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2696
Blazor.PersianDatePicker/wwwroot/datepicker.scss
Normal file
2696
Blazor.PersianDatePicker/wwwroot/datepicker.scss
Normal file
File diff suppressed because it is too large
Load Diff
142
README.md
Normal file
142
README.md
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
# Blazor.PersianDatePicker
|
||||||
|
|
||||||
|
[](https://www.nuget.org/packages/Blazor.PersianDatePicker/)
|
||||||
|
[](https://raw.githubusercontent.com/farshaddavoudi/Blazor.PersianDatePicker/master/LICENSE)
|
||||||
|
|
||||||
|
<img src="https://github.com/fericode/Blazor.PersianDatePicker/blob/master/screenshot.png">
|
||||||
|
|
||||||
|
*After v2.0.0:*
|
||||||
|
|
||||||
|
<img src="https://github.com/fericode/Blazor.PersianDatePicker/blob/master/screenshot2.png">
|
||||||
|
|
||||||
|
*Important fix in v3.2.0:*
|
||||||
|
- When we set the bound parameter value to some date by code (for example in `OnInitialize` method of our page) and then click on the input, the selected date in the datepicker was always today, not that date. It is resolved now. Thanks to [@EsmaeelAmarloo](https://github.com/EsmaeelAmarloo) for creating [the issue](https://github.com/farshaddavoudi/Blazor.PersianDatePicker/issues/60#issuecomment-1820790657).
|
||||||
|
|
||||||
|
## Compatibility:
|
||||||
|
It is compatible and installable on all .NET5, .NET6, .NET7 and .NET8 Blazor projects
|
||||||
|
|
||||||
|
## Usage:
|
||||||
|
|
||||||
|
1- Install **Blazor.PersianDatePicker** from Nuget.org
|
||||||
|
|
||||||
|
2- Add `<script src="_content/Blazor.PersianDatePicker/datepicker.min.js" type="text/javascript"></script>` to your **index.html** or **_Host.cshtml** or **App.razor** *(in .NET8)*
|
||||||
|
|
||||||
|
3- Add `<link href="_content/Blazor.PersianDatePicker/datepicker.css" rel="stylesheet" />` to your **index.html** or **_Host.cshtml** or **App.razor** *(in .NET8)*
|
||||||
|
|
||||||
|
4- Add `@using Blazor.PersianDatePicker` to **_imports.razor**
|
||||||
|
|
||||||
|
5- Use the component **InputPersianDatePicker**
|
||||||
|
|
||||||
|
## Options:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
<InputPersianDatePicker
|
||||||
|
// Html input element id attribute
|
||||||
|
Id="myInputDatePicker" //Optional
|
||||||
|
|
||||||
|
// Bind input value to local variable or dto etc
|
||||||
|
@bind-Value="_myComponentField"
|
||||||
|
|
||||||
|
// Html input element name attribute
|
||||||
|
Name="myInputName" //Optional
|
||||||
|
|
||||||
|
// Control visibility of input
|
||||||
|
Visible="true" //Default: true
|
||||||
|
|
||||||
|
// Disabled make input disabled. This means only showing value and the picker popup won't open
|
||||||
|
Disabled="false" //Default: false
|
||||||
|
|
||||||
|
// Readonly make input readonly. This means the user cannot change the picker value e.g. by typing
|
||||||
|
ReadOnly="true" //Default: true
|
||||||
|
|
||||||
|
// Picker'align relative to input
|
||||||
|
// Options: Align.Right | Align.Left
|
||||||
|
PickerAlign="Align.Right" //Default: Align.Right
|
||||||
|
|
||||||
|
// Show calendar icon on text input
|
||||||
|
ShowCalendarIcon="true" //Default: true
|
||||||
|
|
||||||
|
// Calendar icon position relative to input
|
||||||
|
// Options: IconPosition.BasedOnAlign | IconPosition.Left | IconPosition.Right
|
||||||
|
CalendarIconPosition="IconPosition.BasedOnAlign" //Default: IconPosition.BasedOnAlign
|
||||||
|
|
||||||
|
// Can be used in changing the vertical position of the picker popup relative to the input
|
||||||
|
PickerOffsetTopPositionInPixels="2" //Default: 2
|
||||||
|
|
||||||
|
// Initial value for the input set today
|
||||||
|
InitialValueSetOnToday="false" //Default: false
|
||||||
|
|
||||||
|
// Calendar type for date picker including Dual, Single, etc
|
||||||
|
// Options: Calendar.DualModeJalaliDefault | Calendar.DualModeMiladiDefault | Calendar.SingleModeJalali | Calendar.SingleModeMiladi
|
||||||
|
CalendarType="Calendar.DualModeJalaliDefault" //Default: Calendar.DualModeJalaliDefault
|
||||||
|
|
||||||
|
// Control the digit type showing in the input after selecting by the picker
|
||||||
|
// Options: DigitType.BasedOnCalendar | DigitType.Persian | DigitType.English
|
||||||
|
DigitType="DigitType.BasedOnCalendar" //Default: DigitType.BasedOnCalendar
|
||||||
|
|
||||||
|
// Format of date to show in the input after selecting by picker, e.g. 1400/01/01 or 1400-01-01
|
||||||
|
// Options: DateFormat.yyyy_slash_MM_slash_dd | DateFormat.yyyy_dash_MM_dash_dd
|
||||||
|
DateFormat="DateFormat.yyyy_slash_MM_slash_dd" //Default: DateFormat.yyyy_slash_MM_slash_dd
|
||||||
|
|
||||||
|
// Prevent the user from selecting a date before today
|
||||||
|
MinDateSetOnToday="true" //Default: true
|
||||||
|
|
||||||
|
// Input placeholder
|
||||||
|
Placeholder="Select date"
|
||||||
|
|
||||||
|
// CSS class for input element
|
||||||
|
CssClass="form-control"
|
||||||
|
|
||||||
|
// Inline styles for input element
|
||||||
|
Style="border:1px solid red; width:50%"
|
||||||
|
|
||||||
|
// Choose a theme for changing the look and feel of the picker
|
||||||
|
// Options: PickerTheme.Default | PickerTheme.Dark | PickerTheme.Blue | PickerTheme.Cheerup | PickerTheme.RedBlack
|
||||||
|
// Themes can be seen in the image
|
||||||
|
Theme="PickerTheme.Default"
|
||||||
|
|
||||||
|
// Input change event
|
||||||
|
OnChange="@(() => Console.WriteLine("OK"))"
|
||||||
|
|
||||||
|
// Input text clear event (by pressing close button)
|
||||||
|
OnClear="@(() => Console.WriteLine("Cleared"))" />
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
> #### 💡 You can add multi-instances of InputPersianDatePicker components on a page and all of them work independently without any problem
|
||||||
|
|
||||||
|
## Sample template for fast usage:
|
||||||
|
#### Copy from here then paste in your project; change some options and you're done.
|
||||||
|
|
||||||
|
```razor
|
||||||
|
<InputPersianDatePicker Id="myInputDatePicker"
|
||||||
|
@bind-Value="_variable4"
|
||||||
|
Name="myInputName"
|
||||||
|
Visible="true"
|
||||||
|
Disabled="false"
|
||||||
|
PickerAlign="Align.Right"
|
||||||
|
PickerOffsetTopPositionInPixels="1"
|
||||||
|
InitialValueSetOnToday="false"
|
||||||
|
CalendarType="Calendar.SingleModeJalali"
|
||||||
|
DigitType="DigitType.BasedOnCalendar"
|
||||||
|
DateFormat="DateFormat.yyyy_slash_MM_slash_dd"
|
||||||
|
MinDateSetOnToday="true"
|
||||||
|
Placeholder="Select date"
|
||||||
|
CssClass="form-control"
|
||||||
|
Style="border:1px solid green; width:20%; float:right"
|
||||||
|
Theme="PickerTheme.RedBlack"
|
||||||
|
OnChange="@(() => Console.WriteLine("OK"))" />
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance:
|
||||||
|
|
||||||
|
* `js` size (gzipped) ⇒ **35 kb**
|
||||||
|
|
||||||
|
* `css` size (gzipped) ⇒ **5 kb**
|
||||||
|
|
||||||
|
* `dll` size (gzipped) ⇒ **9 kb**
|
||||||
|
|
||||||
|
|
||||||
|
## Special Thanks:
|
||||||
|
*This project is ported from [pwt.datepicker](https://github.com/babakhani/pwt.datepicker) project with a lot of customizations and optimizations for easy and fast use for Blazor applications. Therefore, I appreciate the great effort of Reza Babakhani @babakhani and all contributors of that project*
|
||||||
|
|
@@ -22,23 +22,23 @@ namespace Shared.DTOs
|
|||||||
[Display(Name = "شناسه")]
|
[Display(Name = "شناسه")]
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
[Display(Name = "عنوان")]
|
[Display(Name = "عنوان")]
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }//
|
||||||
public InvoiceType? invoiceType { get; set; }
|
public InvoiceType? invoiceType { get; set; }//
|
||||||
public int? PatternID { get; set; }
|
public int? PatternID { get; set; }//
|
||||||
public string? PatternTitle { get; set; }
|
public string? PatternTitle { get; set; }//
|
||||||
[Display(Name = "نوع صورتحساب")]
|
[Display(Name = "نوع صورتحساب")]
|
||||||
public string? invoiceTypeTitle { get; set; }
|
public string? invoiceTypeTitle { get; set; }//
|
||||||
public int CustomerID { get; set; }
|
public int CustomerID { get; set; }//
|
||||||
[Display(Name = "مشتری")]
|
[Display(Name = "مشتری")]
|
||||||
public string CustomerName { get; set; }
|
public string CustomerName { get; set; }//
|
||||||
public string? Udate { get; set; }
|
public string? Udate { get; set; }
|
||||||
[Display(Name = "تاریخ صدور")]
|
[Display(Name = "تاریخ صدور")]
|
||||||
public string InvoicIssueDate { get; set; }
|
public string InvoicIssueDate { get; set; }//
|
||||||
public string InvoiceDate { get; set; }
|
public string InvoiceDate { get; set; }//
|
||||||
public bool PreparedtoSendtoTax { get; set; }
|
public bool PreparedtoSendtoTax { get; set; }
|
||||||
public string? Des { get; set; }
|
public string? Des { get; set; }
|
||||||
//مجموع تخفیفات
|
//مجموع تخفیفات
|
||||||
[Display(Name = "مجموع تخفیفات")]
|
[Display(Name = "مجموع تخفیف")]
|
||||||
public decimal? tdis { get; set; }
|
public decimal? tdis { get; set; }
|
||||||
//مجموع مالیات بر ارزش افزوده
|
//مجموع مالیات بر ارزش افزوده
|
||||||
[MaxLength(18)]
|
[MaxLength(18)]
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -10,6 +11,19 @@ namespace Shared
|
|||||||
{
|
{
|
||||||
public static class ExMethod
|
public static class ExMethod
|
||||||
{
|
{
|
||||||
|
public static string ShamciToFormatShamciinFront(this string str)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(str)) return "";
|
||||||
|
return str.Substring(0, 4) + "/" + str.Substring(4, 2) + "/" + str.Substring(6, 2);
|
||||||
|
}
|
||||||
|
public static string ConvertMiladiToShamsiinFront(this DateTime date)
|
||||||
|
{
|
||||||
|
PersianCalendar PersianCal = new PersianCalendar();
|
||||||
|
return PersianCal.GetYear(date).ToString("0000") +
|
||||||
|
PersianCal.GetMonth(date).ToString("00") +
|
||||||
|
PersianCal.GetDayOfMonth(date).ToString("00")
|
||||||
|
;
|
||||||
|
}
|
||||||
public static string GetEnumDisplayName(this Enum enumType)
|
public static string GetEnumDisplayName(this Enum enumType)
|
||||||
{
|
{
|
||||||
return enumType.GetType().GetMember(enumType.ToString())
|
return enumType.GetType().GetMember(enumType.ToString())
|
||||||
|
@@ -20,11 +20,13 @@
|
|||||||
<select @bind="Cod.UnitID" class="form-control" aria-label="Default select example" id="inputUnitID">
|
<select @bind="Cod.UnitID" class="form-control" aria-label="Default select example" id="inputUnitID">
|
||||||
@if (Cod.UnitID > 0)
|
@if (Cod.UnitID > 0)
|
||||||
{
|
{
|
||||||
<option value="0" style="color: #b5b5b5" selected>انتخاب کنید...</option>
|
<option value="0" style="color: #b5b5b5">انتخاب کنید...</option>
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<option value="0" style="color: #b5b5b5">انتخاب کنید...</option>
|
<option value="0" style="color: #b5b5b5" selected>انتخاب کنید...</option>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (Unitrequest != null)
|
@if (Unitrequest != null)
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
@using Front.Services
|
@using Front.Services
|
||||||
@using Shared.DTOs
|
@using Shared.DTOs
|
||||||
|
@using Shared
|
||||||
@inject HttpClientController hc;
|
@inject HttpClientController hc;
|
||||||
<form>
|
<form>
|
||||||
@* alert *@
|
@* alert *@
|
||||||
@@ -12,14 +13,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-2">
|
||||||
<label class="col-sm-4 col-form-label" style="color:red" for="inputTitle">نام کالا</label>
|
<label class="col-sm-4 col-form-label" style="color:red" for="inputTitle">عنوان</label>
|
||||||
<InputText @bind-Value="Cod.Title" type="text" class="form-control" id="inputTitle" placeholder="نام کالا" />
|
<InputText @bind-Value="invoice.Title" type="text" class="form-control" id="inputTitle" placeholder="عنوان" />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-2">
|
||||||
<label class="col-sm-5 col-form-label" style="color:red" for="inputUnitID">واحد اندازه گیزی</label>
|
<label class="col-sm-4 col-form-label" for="inputinvoiceTypeTitle">نوع</label>
|
||||||
<select @bind="Cod.UnitID" class="form-control" aria-label="Default select example" id="inputUnitID">
|
<select @bind="invoice.invoiceType" class="form-control" aria-label="Default select example" id="inputinvoiceTypeTitle">
|
||||||
@if (Cod.UnitID > 0)
|
@if (!invoice.invoiceType.HasValue)
|
||||||
{
|
{
|
||||||
<option value="0" style="color: #b5b5b5" selected>انتخاب کنید...</option>
|
<option value="0" style="color: #b5b5b5" selected>انتخاب کنید...</option>
|
||||||
}
|
}
|
||||||
@@ -28,11 +29,42 @@
|
|||||||
<option value="0" style="color: #b5b5b5">انتخاب کنید...</option>
|
<option value="0" style="color: #b5b5b5">انتخاب کنید...</option>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (Unitrequest != null)
|
|
||||||
|
@foreach (InvoiceType i in Enum.GetValues(typeof(InvoiceType)))
|
||||||
{
|
{
|
||||||
foreach (var item in Unitrequest)
|
|
||||||
|
if (invoice.invoiceType == i)
|
||||||
{
|
{
|
||||||
if (Cod.UnitID == item.ID)
|
<option value="@i" selected>@i.GetEnumDisplayName()</option>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<option value="@i">@i.GetEnumDisplayName()</option>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-md-2">
|
||||||
|
<label class="col-sm-8 col-form-label" for="inputPatternID">الگو صورتحساب</label>
|
||||||
|
<select @bind="invoice.PatternID" class="form-control" aria-label="Default select example" id="inputPatternID">
|
||||||
|
@if (invoice.PatternID == null || invoice.PatternID ==0)
|
||||||
|
{
|
||||||
|
<option value="0" style="color: #b5b5b5" selected>انتخاب کنید...</option>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<option value="0" style="color: #b5b5b5">انتخاب کنید...</option>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Patterns != null)
|
||||||
|
{
|
||||||
|
foreach (var item in Patterns)
|
||||||
|
{
|
||||||
|
if (invoice.PatternID == item.ID)
|
||||||
{
|
{
|
||||||
<option value="@item.ID" selected>@item.Title</option>
|
<option value="@item.ID" selected>@item.Title</option>
|
||||||
}
|
}
|
||||||
@@ -44,23 +76,79 @@
|
|||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group col-md-2">
|
||||||
|
<label class="col-sm-5 col-form-label" style="color:red" for="inputCustomerID">مشتری</label>
|
||||||
|
<select @bind="invoice.CustomerID" class="form-control" aria-label="Default select example" id="inputCustomerID">
|
||||||
|
@if (invoice.CustomerID == null || invoice.CustomerID == 0)
|
||||||
|
{
|
||||||
|
<option value="0" style="color: #b5b5b5" selected>انتخاب کنید...</option>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<option value="0" style="color: #b5b5b5">انتخاب کنید...</option>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Cus != null)
|
||||||
|
{
|
||||||
|
foreach (var item in Cus)
|
||||||
|
{
|
||||||
|
if (invoice.CustomerID == item.ID)
|
||||||
|
{
|
||||||
|
<option value="@item.ID" selected>@item.CustomerName</option>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<option value="@item.ID">@item.CustomerName</option>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group col-md-2">
|
||||||
|
<label class="col-sm-5 col-form-label" for="inputInvoicIssueDate">تاریخ صدور</label>
|
||||||
|
<InputText style=" text-align: center;" @bind-Value="invoice.InvoicIssueDate" type="text" class="form-control" id="inputInvoicIssueDate" placeholder="تاریخ صدور" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-2">
|
||||||
|
<label class="col-sm-4 col-form-label" for="inputInvoiceDate">تاریخ</label>
|
||||||
|
<InputText style=" text-align: center;" @bind-Value="invoice.InvoiceDate" type="text" class="form-control" id="inputInvoiceDate" placeholder="تاریخ" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br /> <hr class="hr" />
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-md-6">
|
<Tabs NavStyle="NavStyle.VerticalUnderline">
|
||||||
<label class="col-sm-5 col-form-label">شناسه مالیاتی کالا</label>
|
<Tab Title="آیتم ها" IsActive="true">
|
||||||
<InputText @bind-Value="Cod.TaxID" type="text" class="form-control" id="inputTaxID" placeholder="شناسه مالیاتی کالا" />
|
<Content>
|
||||||
|
<p class="ms-3">This is the placeholder content for the <b>Home</b> tab.</p>
|
||||||
|
</Content>
|
||||||
|
</Tab>
|
||||||
|
<Tab Title="پرداختی ها">
|
||||||
|
<Content>
|
||||||
|
<p class="ms-3">This is the placeholder content for the <b>Profile</b> tab.</p>
|
||||||
|
</Content>
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<hr class="hr" />
|
||||||
<label style="color:red" class="col-sm-5 col-form-label">% نرخ مالیات کالا</label>
|
<br />
|
||||||
<NumberInput @bind-Value="Cod.TaxRate" type="text" class="form-control" id="inputTaxRate" placeholder="نرخ مالیات کالا" />
|
<div class="row g-3">
|
||||||
|
<div class="form-group col-md-8">
|
||||||
|
<label class="col-sm-4 col-form-label" for="inputdes">توضیحات</label>
|
||||||
|
<InputText @bind-Value="invoice.Des" type="text" class="form-control" id="inputdes" placeholder="توضیحات" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-4">
|
||||||
|
<label class="col-sm-4 col-form-label" for="inputUdate">آخرین ویرایش</label>
|
||||||
|
<InputText style=" text-align: center;" @bind-Value="invoice.Udate" class="form-control" id="inputUdate" readonly />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
@if (Cod.ID == 0)
|
@if (invoice.ID == 0)
|
||||||
{
|
{
|
||||||
<Button class="mt-3" Color="ButtonColor.Success" @onclick="OnClickAdd" Type="ButtonType.Button">
|
<Button class="mt-3" Color="ButtonColor.Success" @onclick="OnClickAdd" Type="ButtonType.Button">
|
||||||
جدید
|
جدید
|
||||||
@@ -78,11 +166,14 @@ else
|
|||||||
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
// alert
|
// alert
|
||||||
AlertColor alertColor = AlertColor.Primary;
|
AlertColor alertColor = AlertColor.Primary;
|
||||||
IconName alertIconName = IconName.CheckCircleFill;
|
IconName alertIconName = IconName.CheckCircleFill;
|
||||||
bool Hidealert = true;
|
bool Hidealert = true;
|
||||||
string alertMessage = "";
|
string alertMessage = "";
|
||||||
|
[Parameter] public List<ForCustomerSearch> Cus { get; set; }
|
||||||
|
[Parameter] public List<IdName<int>> Patterns { get; set; }
|
||||||
[Parameter] public InvoiceDTO invoice { get; set; }
|
[Parameter] public InvoiceDTO invoice { get; set; }
|
||||||
[Parameter] public EventCallback<ActionInResultComponent> OnMultipleOfThree { get; set; }
|
[Parameter] public EventCallback<ActionInResultComponent> OnMultipleOfThree { get; set; }
|
||||||
// [Parameter] public List<IdName<int>>? Unitrequest { get; set; }
|
// [Parameter] public List<IdName<int>>? Unitrequest { get; set; }
|
||||||
@@ -91,7 +182,6 @@ else
|
|||||||
|
|
||||||
protected override Task OnParametersSetAsync()
|
protected override Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
|
|
||||||
result = new ActionInResultComponent()
|
result = new ActionInResultComponent()
|
||||||
{
|
{
|
||||||
Status = ComponentStatus.fild
|
Status = ComponentStatus.fild
|
||||||
@@ -119,7 +209,7 @@ else
|
|||||||
public async Task OnClickDelete()
|
public async Task OnClickDelete()
|
||||||
{
|
{
|
||||||
|
|
||||||
var rsp = await hc.Delete($"Cod/Delete/{Cod.ID}");
|
var rsp = await hc.Delete($"Cod/Delete/{invoice.ID}");
|
||||||
if (rsp.IsSuccessStatusCode)
|
if (rsp.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
var request = await rsp.Content.ReadFromJsonAsync<bool>();
|
var request = await rsp.Content.ReadFromJsonAsync<bool>();
|
||||||
@@ -144,54 +234,58 @@ else
|
|||||||
}
|
}
|
||||||
public async Task OnClickUpdate()
|
public async Task OnClickUpdate()
|
||||||
{
|
{
|
||||||
if (Cod.UnitID > 0 && Cod.TaxRate > 0 && !string.IsNullOrEmpty(Cod.Title))
|
// if (Cod.UnitID > 0 && Cod.TaxRate > 0 && !string.IsNullOrEmpty(Cod.Title))
|
||||||
{
|
// {
|
||||||
|
|
||||||
var rsp = await hc.Put<RCOD>("Cod/Update", Cod);
|
// var rsp = await hc.Put<RCOD>("Cod/Update", Cod);
|
||||||
if (rsp.IsSuccessStatusCode)
|
// if (rsp.IsSuccessStatusCode)
|
||||||
{
|
// {
|
||||||
var request = await rsp.Content.ReadFromJsonAsync<bool>();
|
// var request = await rsp.Content.ReadFromJsonAsync<bool>();
|
||||||
if (request)
|
// if (request)
|
||||||
{
|
// {
|
||||||
result.Status = ComponentStatus.success;
|
// result.Status = ComponentStatus.success;
|
||||||
result.Action = ComponentAction.update;
|
// result.Action = ComponentAction.update;
|
||||||
await OnMultipleOfThree.InvokeAsync(result);
|
// await OnMultipleOfThree.InvokeAsync(result);
|
||||||
}
|
// }
|
||||||
else ShowDangerAlert("خطایی در اجرای عملیات رخ داده");
|
// else ShowDangerAlert("خطایی در اجرای عملیات رخ داده");
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
var request = await rsp.Content.ReadFromJsonAsync<List<string>>();
|
// var request = await rsp.Content.ReadFromJsonAsync<List<string>>();
|
||||||
ShowDangerAlert(request[0]);
|
// ShowDangerAlert(request[0]);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else ShowDangerAlert("فیلدهای قرمز باید مقدار دهی شوند");
|
// else ShowDangerAlert("فیلدهای قرمز باید مقدار دهی شوند");
|
||||||
}
|
}
|
||||||
public async Task OnClickAdd()
|
public async Task OnClickAdd()
|
||||||
{
|
{
|
||||||
if (Cod.UnitID > 0 && Cod.TaxRate > 0 && !string.IsNullOrEmpty(Cod.Title))
|
// if (Cod.UnitID > 0 && Cod.TaxRate > 0 && !string.IsNullOrEmpty(Cod.Title))
|
||||||
{
|
// {
|
||||||
|
|
||||||
var rsp = await hc.Post<RCOD>("Cod/Add", Cod);
|
// var rsp = await hc.Post<RCOD>("Cod/Add", Cod);
|
||||||
if (rsp.IsSuccessStatusCode)
|
// if (rsp.IsSuccessStatusCode)
|
||||||
{
|
// {
|
||||||
var request = await rsp.Content.ReadFromJsonAsync<bool>();
|
// var request = await rsp.Content.ReadFromJsonAsync<bool>();
|
||||||
|
|
||||||
if (request)
|
// if (request)
|
||||||
{
|
// {
|
||||||
result.Status = ComponentStatus.success;
|
// result.Status = ComponentStatus.success;
|
||||||
result.Action = ComponentAction.add;
|
// result.Action = ComponentAction.add;
|
||||||
await OnMultipleOfThree.InvokeAsync(result);
|
// await OnMultipleOfThree.InvokeAsync(result);
|
||||||
}
|
// }
|
||||||
else ShowDangerAlert("خطایی در اجرای عملیات رخ داده");
|
// else ShowDangerAlert("خطایی در اجرای عملیات رخ داده");
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
|
|
||||||
var request = await rsp.Content.ReadFromJsonAsync<List<string>>();
|
// var request = await rsp.Content.ReadFromJsonAsync<List<string>>();
|
||||||
ShowDangerAlert(request[0]);
|
// ShowDangerAlert(request[0]);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else ShowDangerAlert("فیلدهای قرمز باید مقدار دهی شوند");
|
// else ShowDangerAlert("فیلدهای قرمز باید مقدار دهی شوند");
|
||||||
|
}
|
||||||
|
public async Task<bool> Validate()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -114,7 +114,7 @@
|
|||||||
@code {
|
@code {
|
||||||
private string? customerName;
|
private string? customerName;
|
||||||
public IEnumerable<ForCustomerSearch>? customers;
|
public IEnumerable<ForCustomerSearch>? customers;
|
||||||
|
public List<IdName<int>> Patterns { get; set; }
|
||||||
private async Task<AutoCompleteDataProviderResult<ForCustomerSearch>> CustomersDataProvider(AutoCompleteDataProviderRequest<ForCustomerSearch> request)
|
private async Task<AutoCompleteDataProviderResult<ForCustomerSearch>> CustomersDataProvider(AutoCompleteDataProviderRequest<ForCustomerSearch> request)
|
||||||
{
|
{
|
||||||
if (customers is null) // pull customers only one time for client-side autocomplete
|
if (customers is null) // pull customers only one time for client-side autocomplete
|
||||||
@@ -210,11 +210,28 @@
|
|||||||
}
|
}
|
||||||
public async Task InvoiceItem(int ID)
|
public async Task InvoiceItem(int ID)
|
||||||
{
|
{
|
||||||
|
if (customers is null)
|
||||||
|
customers = await GetCustomers();
|
||||||
|
if (Patterns == null || Patterns.Count < 0)
|
||||||
|
{
|
||||||
|
var rsp = await hc.Get("Invoice/GetPatterns");
|
||||||
|
if (rsp.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
Patterns = await rsp.Content.ReadFromJsonAsync<List<IdName<int>>>();
|
||||||
|
}
|
||||||
|
}
|
||||||
var parameters = new Dictionary<string, object>();
|
var parameters = new Dictionary<string, object>();
|
||||||
|
|
||||||
if (ID == 0) parameters.Add("Invoice", new InvoiceDTO() { ID = 0 });
|
if (ID == 0) parameters.Add("Invoice", new InvoiceDTO()
|
||||||
|
{
|
||||||
|
ID = 0,
|
||||||
|
InvoiceDate = DateTime.Now.ConvertMiladiToShamsiinFront().ShamciToFormatShamciinFront(),
|
||||||
|
InvoicIssueDate = DateTime.Now.ConvertMiladiToShamsiinFront().ShamciToFormatShamciinFront(),
|
||||||
|
Udate = DateTime.Now.ConvertMiladiToShamsiinFront().ShamciToFormatShamciinFront()
|
||||||
|
});
|
||||||
else parameters.Add("invoice", request.list.Where(w => w.ID == ID).First().Clone());
|
else parameters.Add("invoice", request.list.Where(w => w.ID == ID).First().Clone());
|
||||||
|
parameters.Add("Patterns", Patterns);
|
||||||
|
parameters.Add("Cus", customers);
|
||||||
parameters.Add("OnMultipleOfThree", EventCallback.Factory.Create<ActionInResultComponent>(this, CallBackCustomerItem));
|
parameters.Add("OnMultipleOfThree", EventCallback.Factory.Create<ActionInResultComponent>(this, CallBackCustomerItem));
|
||||||
await modal.ShowAsync<InvoiceItem>(title: ID == 0 ? "صورتحساب جدید" : "ویرایش اطلاعات", parameters: parameters);
|
await modal.ShowAsync<InvoiceItem>(title: ID == 0 ? "صورتحساب جدید" : "ویرایش اطلاعات", parameters: parameters);
|
||||||
|
|
||||||
|
@@ -33,9 +33,9 @@ builder.Services.AddScoped(sp => new UserAuthenticationDTO()
|
|||||||
}) ;
|
}) ;
|
||||||
|
|
||||||
|
|
||||||
//builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("https://localhost:7075/api/") });
|
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("https://localhost:7075/api/") });
|
||||||
|
|
||||||
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("http://localhost:5271/api/") });
|
//builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("http://localhost:5271/api/") });
|
||||||
|
|
||||||
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("fa-Ir");
|
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("fa-Ir");
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user