diff --git a/README.md b/README.md index 393d611..df0c1a8 100644 --- a/README.md +++ b/README.md @@ -369,6 +369,10 @@ Workflow Получение произведения двух чисел. +:new: Round +Округление числа по математическим правилам, а также в большую и меньшу стороны. + + :new: Sum Получение суммы двух чисел. diff --git a/Source/Tools/Math/Math Tests/Math Tests.csproj b/Source/Tools/Math/Math Tests/Math Tests.csproj index f78b8bd..568ceb0 100644 --- a/Source/Tools/Math/Math Tests/Math Tests.csproj +++ b/Source/Tools/Math/Math Tests/Math Tests.csproj @@ -96,7 +96,7 @@ - + diff --git a/Source/Tools/Math/Math Tests/Workflow/DiffTests.cs b/Source/Tools/Math/Math Tests/Workflow/DiffTests.cs deleted file mode 100644 index dd1df2a..0000000 --- a/Source/Tools/Math/Math Tests/Workflow/DiffTests.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Activities; -using System.Collections.Generic; -using Microsoft.Xrm.Sdk; -using Microsoft.Xrm.Sdk.Workflow; -using PZone.MathTools.Workflow; -using PZone.Xrm.Testing; -using PZone.Xrm.Testing.Workflow; - - -namespace PZone.Tests.MathTools.Workflow -{ - [TestClass] - public class DiffTests - { - [TestMethod] - public void Success() - { - - } - } -} diff --git a/Source/Tools/Math/Math Tests/Workflow/RoundTests.cs b/Source/Tools/Math/Math Tests/Workflow/RoundTests.cs new file mode 100644 index 0000000..bcbe1e8 --- /dev/null +++ b/Source/Tools/Math/Math Tests/Workflow/RoundTests.cs @@ -0,0 +1,134 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Activities; +using System.Collections.Generic; +using Microsoft.Xrm.Sdk; +using Microsoft.Xrm.Sdk.Workflow; +using PZone.MathTools.Workflow; +using PZone.Xrm.Testing; +using PZone.Xrm.Testing.Workflow; + + +namespace PZone.Tests.MathTools.Workflow +{ + [TestClass] + public class RoundTests + { + [TestMethod] + public void Success() + { + var action = new Round(); + var invoker = new WorkflowInvoker(action); + invoker.Extensions.Add(() => new FakeTracingService()); + invoker.Extensions.Add(() => new FakeWorkflowContext()); + invoker.Extensions.Add(() => new FakeOrganizationServiceFactory(new FakeOrganizationService())); + + var result = invoker.Invoke(new Dictionary + { + { "Value", 2.22m }, + { "Digits", 1 } + }); + Assert.AreEqual(2.2m, result["RoundValue"]); + Assert.AreEqual(2.3m, result["CeilingValue"]); + Assert.AreEqual(2.2m, result["FloorValue"]); + + result = invoker.Invoke(new Dictionary + { + { "Value", 2.22m }, + { "Digits", 0 } + }); + Assert.AreEqual(2m, result["RoundValue"]); + Assert.AreEqual(3m, result["CeilingValue"]); + Assert.AreEqual(2m, result["FloorValue"]); + + result = invoker.Invoke(new Dictionary + { + { "Value", 2.22m }, + { "Digits", 2 } + }); + Assert.AreEqual(2.22m, result["RoundValue"]); + Assert.AreEqual(2.22m, result["CeilingValue"]); + Assert.AreEqual(2.22m, result["FloorValue"]); + + result = invoker.Invoke(new Dictionary + { + { "Value", 2.22m }, + { "Digits", 3 } + }); + Assert.AreEqual(2.22m, result["RoundValue"]); + Assert.AreEqual(2.22m, result["CeilingValue"]); + Assert.AreEqual(2.22m, result["FloorValue"]); + + result = invoker.Invoke(new Dictionary + { + { "Value", 2.26m }, + { "Digits", 1 } + }); + Assert.AreEqual(2.3m, result["RoundValue"]); + Assert.AreEqual(2.3m, result["CeilingValue"]); + Assert.AreEqual(2.2m, result["FloorValue"]); + + result = invoker.Invoke(new Dictionary + { + { "Value", 2.25m }, + { "Digits", 1 } + }); + Assert.AreEqual(2.3m, result["RoundValue"]); + Assert.AreEqual(2.3m, result["CeilingValue"]); + Assert.AreEqual(2.2m, result["FloorValue"]); + + result = invoker.Invoke(new Dictionary + { + { "Value", 2.2m }, + { "Digits", 0 } + }); + Assert.AreEqual(2m, result["RoundValue"]); + Assert.AreEqual(3m, result["CeilingValue"]); + Assert.AreEqual(2m, result["FloorValue"]); + + result = invoker.Invoke(new Dictionary + { + { "Value", 2.5m }, + { "Digits", 0 } + }); + Assert.AreEqual(3m, result["RoundValue"]); + Assert.AreEqual(3m, result["CeilingValue"]); + Assert.AreEqual(2m, result["FloorValue"]); + + result = invoker.Invoke(new Dictionary + { + { "Value", -2.22m }, + { "Digits", 1 } + }); + Assert.AreEqual(-2.2m, result["RoundValue"]); + Assert.AreEqual(-2.2m, result["CeilingValue"]); + Assert.AreEqual(-2.3m, result["FloorValue"]); + + result = invoker.Invoke(new Dictionary + { + { "Value", -1.22m }, + { "Digits", 1 } + }); + Assert.AreEqual(-1.2m, result["RoundValue"]); + Assert.AreEqual(-1.2m, result["CeilingValue"]); + Assert.AreEqual(-1.3m, result["FloorValue"]); + + result = invoker.Invoke(new Dictionary + { + { "Value", -1.25m }, + { "Digits", 1 } + }); + Assert.AreEqual(-1.3m, result["RoundValue"]); + Assert.AreEqual(-1.2m, result["CeilingValue"]); + Assert.AreEqual(-1.3m, result["FloorValue"]); + + result = invoker.Invoke(new Dictionary + { + { "Value", -1.15m }, + { "Digits", 1 } + }); + Assert.AreEqual(-1.2m, result["RoundValue"]); + Assert.AreEqual(-1.1m, result["CeilingValue"]); + Assert.AreEqual(-1.2m, result["FloorValue"]); + } + } +} \ No newline at end of file diff --git a/Source/Tools/Math/Math/Math.csproj b/Source/Tools/Math/Math/Math.csproj index 20c9cfd..0887f6f 100644 --- a/Source/Tools/Math/Math/Math.csproj +++ b/Source/Tools/Math/Math/Math.csproj @@ -41,6 +41,7 @@ + diff --git a/Source/Tools/Math/Math/Properties/AssemblyInfo.cs b/Source/Tools/Math/Math/Properties/AssemblyInfo.cs index 8d207dc..3d412dd 100644 --- a/Source/Tools/Math/Math/Properties/AssemblyInfo.cs +++ b/Source/Tools/Math/Math/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("8.0.3.6")] -[assembly: AssemblyFileVersion("8.0.3.6")] +[assembly: AssemblyVersion("8.0.3.7")] +[assembly: AssemblyFileVersion("8.0.3.7")] diff --git a/Source/Tools/Math/Math/Workflow/Round.cs b/Source/Tools/Math/Math/Workflow/Round.cs new file mode 100644 index 0000000..5c769b6 --- /dev/null +++ b/Source/Tools/Math/Math/Workflow/Round.cs @@ -0,0 +1,61 @@ +using System; +using System.Activities; +using Microsoft.Xrm.Sdk.Workflow; +using PZone.Xrm.Workflow; + + +namespace PZone.MathTools.Workflow +{ + /// + /// Округление числа по математическим правилам, а также в большую и меньшу стороны. + /// + public class Round : WorkflowBase + { + [Input("Value")] + [RequiredArgument] + public InArgument Value { get; set; } + + + [Input("Digits")] + [RequiredArgument] + public InArgument Digits { get; set; } + + + [Output("Round")] + public OutArgument RoundValue { get; set; } + + + [Output("Ceiling")] + public OutArgument CeilingValue { get; set; } + + + [Output("Floor")] + public OutArgument FloorValue { get; set; } + + + protected override void Execute(Context context) + { + var value = Value.Get(context); + var digits = Digits.Get(context); + + if (digits < 0) + throw new InvalidWorkflowException("Digits value cannot be negative."); + + var m = digits == 0 ? 1 : (decimal)Math.Pow(10, digits); + var tmp = value * m; + var multiplier = value > 0 ? 1 : -1; + + if (tmp % 1 == 0) + { + RoundValue.Set(context, value); + CeilingValue.Set(context, value); + FloorValue.Set(context, value); + return; + } + + RoundValue.Set(context, Math.Abs(Math.Round(value, digits, MidpointRounding.AwayFromZero)) * multiplier); + CeilingValue.Set(context, Math.Ceiling(tmp) / m); + FloorValue.Set(context, Math.Floor(tmp) / m); + } + } +} \ No newline at end of file