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