diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 7d89d00b2c..45e7184c39 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -1122,7 +1122,7 @@ "AutoLicenseRenewalIsNotEnabled": "Auto license renewal is not enabled.", "SetAsDefaultPaymentMethod": "Set as default payment method", "{0}PerAdditionalDeveloper": "{0} per additional developer", - "CardAlias": "Card Alias", + "CardAlias": "Card Alias (Optional)", "AbpDoesNotSaveYourPaymentDetails_Description": "The payment data will be saved in {2} security vaults and you can remove stored data anytime. Enabling auto-renewal ensures that your ABP subscription will automatically renew prior to expiration, providing a valid credit card. Disabling auto-renewal means you will have to renew your subscription manually. To continue your project development without interruption, we suggest you enable the Auto-Renewal option.", "AddBillingInformation": "Add Billing Information", "YouHaveNoCardsSaved": "You have no cards saved.", @@ -1133,6 +1133,13 @@ "BillingDetails": "Billing Details", "ThereIsNoDeveloper": "There is no developer.", "CardDetails": "Debit/Credit Card Details", - "NoActiveLicence": "You are not eligible for this action! You have no active license." + "NoActiveLicence": "You are not eligible for this action! You have no active license.", + "YearCantBeNull": "Year field cannot be empty.", + "CardHolderName": "Name on Card", + "ExpireDate": "Expiration Date", + "DisplayName:ExpireDate": "Expiration Date", + "DisplayName:CardHolderName": "Name on Card", + "CreditCardNumberLengthWarning": "Invalid card number", + "ExpirationWarning": "Invalid expiration date" } } \ No newline at end of file diff --git a/docs/en/Concurrency-Check.md b/docs/en/Concurrency-Check.md index bf31d3db10..25e60713c7 100644 --- a/docs/en/Concurrency-Check.md +++ b/docs/en/Concurrency-Check.md @@ -29,6 +29,8 @@ public interface IHasConcurrencyStamp * While a new record is **creating**, if the entity implements the `IHasConcurrencyStamp` interface, ABP Framework automatically sets a unique value to the **ConcurrencyStamp** property. * While a record is **updating**, ABP Framework compares the **ConcurrencyStamp** property of the entity with the provided **ConcurrencyStamp** value by the user and if the values match, it automatically updates the **ConcurrencyStamp** property with the new unique value. If there is a mismatch, `AbpDbConcurrencyException` is thrown. +> If there is a unit of work, you need to call the [SaveChangesAsync](./Unit-Of-Work.md#savechangesasync) method to get the generated `ConcurrencyStamp` when creating or updating. + **Example: Applying Concurrency Control for the Book Entity** Implement the `IHasConcurrencyStamp` interface for your entity: @@ -74,8 +76,8 @@ public class BookAppService : ApplicationService, IBookAppService book.ConcurrencyStamp = input.ConcurrencyStamp; //set other input values to the entity ... - - await BookRepository.UpdateAsync(book); + //use autoSave: true to get the latest ConcurrencyStamp + await BookRepository.UpdateAsync(book, autoSave: true); } } ``` @@ -134,8 +136,8 @@ public class BookAppService : ApplicationService, IBookAppService book.ConcurrencyStamp = input.ConcurrencyStamp; //set other input values to the entity ... - - await BookRepository.UpdateAsync(book); + //use autoSave: true to get the latest ConcurrencyStamp + await BookRepository.UpdateAsync(book, autoSave: true); } } ``` diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs index ae018a88c7..60e6d99e34 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs @@ -233,6 +233,8 @@ public abstract class ProjectCreationCommandBase var skipCache = commandLineArgs.Options.ContainsKey(Options.SkipCache.Long) || commandLineArgs.Options.ContainsKey(Options.SkipCache.Short); + var trustUserVersion = !version.IsNullOrEmpty() && commandLineArgs.Options.ContainsKey(Options.TrustUserVersion.Long) || commandLineArgs.Options.ContainsKey(Options.TrustUserVersion.Short); + return new ProjectBuildArgs( solutionName, template, @@ -251,7 +253,8 @@ public abstract class ProjectCreationCommandBase pwa, theme, themeStyle, - skipCache + skipCache, + trustUserVersion ); } @@ -902,6 +905,11 @@ public abstract class ProjectCreationCommandBase public const string Long = "skip-cache"; } + public static class TrustUserVersion + { + public const string Short = "tv"; + public const string Long = "trust-version"; + } public static class Tiered { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs index 0415b088cc..e39daf60c8 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs @@ -65,7 +65,8 @@ public class AbpIoSourceCodeStore : ISourceCodeStore, ITransientDependency string version = null, string templateSource = null, bool includePreReleases = false, - bool skipCache = false) + bool skipCache = false, + bool trustUserVersion = false) { DirectoryHelper.CreateIfNotExists(CliPaths.TemplateCache); var userSpecifiedVersion = version != null; @@ -96,33 +97,36 @@ public class AbpIoSourceCodeStore : ISourceCodeStore, ITransientDependency var templateVersion = SemanticVersion.Parse(version); var outputWarning = false; - if (currentCliVersion.Major != templateVersion.Major || currentCliVersion.Minor != templateVersion.Minor) + if (!trustUserVersion) { - // major and minor version are different - outputWarning = true; - } - else if (currentCliVersion.Major == templateVersion.Major && - currentCliVersion.Minor == templateVersion.Minor && - currentCliVersion.Patch < templateVersion.Patch) - { - // major and minor version are same but patch version is lower - outputWarning = true; - } - else if(currentCliVersion.Major == templateVersion.Major && - currentCliVersion.Minor == templateVersion.Minor && - currentCliVersion.Patch == templateVersion.Patch && - currentCliVersion.IsPrerelease && templateVersion.IsPrerelease) - { - // major and minor and patch version are same but prerelease version may be lower - var cliRcVersion = currentCliVersion.ReleaseLabels.LastOrDefault(); - var templateRcVersion = templateVersion.ReleaseLabels.LastOrDefault(); - if (cliRcVersion != null && templateRcVersion != null) + if (currentCliVersion.Major != templateVersion.Major || currentCliVersion.Minor != templateVersion.Minor) + { + // major and minor version are different + outputWarning = true; + } + else if (currentCliVersion.Major == templateVersion.Major && + currentCliVersion.Minor == templateVersion.Minor && + currentCliVersion.Patch < templateVersion.Patch) + { + // major and minor version are same but patch version is lower + outputWarning = true; + } + else if(currentCliVersion.Major == templateVersion.Major && + currentCliVersion.Minor == templateVersion.Minor && + currentCliVersion.Patch == templateVersion.Patch && + currentCliVersion.IsPrerelease && templateVersion.IsPrerelease) { - if (int.TryParse(cliRcVersion, out var cliRcVersionNumber) && int.TryParse(templateRcVersion, out var templateRcVersionNumber)) + // major and minor and patch version are same but prerelease version may be lower + var cliRcVersion = currentCliVersion.ReleaseLabels.LastOrDefault(); + var templateRcVersion = templateVersion.ReleaseLabels.LastOrDefault(); + if (cliRcVersion != null && templateRcVersion != null) { - if (cliRcVersionNumber < templateRcVersionNumber) + if (int.TryParse(cliRcVersion, out var cliRcVersionNumber) && int.TryParse(templateRcVersion, out var templateRcVersionNumber)) { - outputWarning = true; + if (cliRcVersionNumber < templateRcVersionNumber) + { + outputWarning = true; + } } } } @@ -140,20 +144,19 @@ public class AbpIoSourceCodeStore : ISourceCodeStore, ITransientDependency ? $"> dotnet tool install -g volo.abp.cli --version \"{templateVersion.Major}.{templateVersion.Minor}.*\"" : $"> dotnet tool install -g volo.abp.cli --version {templateVersion}"); - if (!userSpecifiedVersion) + if (userSpecifiedVersion) { - version = currentCliVersion.ToString(); Logger.LogWarning($"We have changed the template version as the cli version."); Logger.LogWarning($"New version: {version}"); } } - if (!await IsVersionExists(name, version)) + if (!trustUserVersion && !await IsVersionExists(name, version)) { throw new Exception("There is no version found with given version: " + version); } - var nugetVersion = (await GetTemplateNugetVersionAsync(name, type, version)) ?? version; + var nugetVersion = await GetTemplateNugetVersionAsync(name, type, version) ?? version; if (!string.IsNullOrWhiteSpace(templateSource) && !IsNetworkSource(templateSource)) { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ISourceCodeStore.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ISourceCodeStore.cs index c503b87b6e..813f524982 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ISourceCodeStore.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ISourceCodeStore.cs @@ -11,6 +11,7 @@ public interface ISourceCodeStore [CanBeNull] string version = null, [CanBeNull] string templateSource = null, bool includePreReleases = false, - bool skipCache = false + bool skipCache = false, + bool trustUserVersion = false ); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs index cdeba4eaeb..220c2cbe9b 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs @@ -15,6 +15,8 @@ public class ProjectBuildArgs [CanBeNull] public string Version { get; set; } + public bool TrustUserVersion { get; set; } + public DatabaseProvider DatabaseProvider { get; set; } public DatabaseManagementSystem DatabaseManagementSystem { get; set; } @@ -69,7 +71,8 @@ public class ProjectBuildArgs bool pwa = false, Theme? theme = null, ThemeStyle? themeStyle = null, - bool skipCache = false) + bool skipCache = false, + bool trustUserVersion = false) { SolutionName = Check.NotNull(solutionName, nameof(solutionName)); TemplateName = templateName; @@ -89,5 +92,6 @@ public class ProjectBuildArgs Theme = theme; ThemeStyle = themeStyle; SkipCache = skipCache; + TrustUserVersion = trustUserVersion; } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs index 9ab587e3ec..0865049382 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs @@ -68,7 +68,8 @@ public class TemplateProjectBuilder : IProjectBuilder, ITransientDependency SourceCodeTypes.Template, args.Version, args.TemplateSource, - args.ExtraProperties.ContainsKey(NewCommand.Options.Preview.Long) + args.ExtraProperties.ContainsKey(NewCommand.Options.Preview.Long), + trustUserVersion: args.TrustUserVersion ); ConfigureThemeOptions(args, templateFile.Version);