using System; using System.Collections.Generic; using System.Linq; using Centron.BusinessLogic; using Centron.BusinessLogic.Administration.Rights; using Centron.BusinessLogic.EmployeeArea; using Centron.BusinessLogic.Sales.Receipts; using Centron.BusinessLogic.Sales.Receipts.DataAndResults; using Centron.BusinessLogic.Sales.Receipts.Internal; using Centron.BusinessLogic.WebServices.Accounts; using Centron.BusinessLogic.WebServices.Administration.Rights; using Centron.BusinessLogic.WebServices.Sales.Receipts; using Centron.DAO; using Centron.Data.Entities.Administration.Logins; using Centron.Data.Entities.Sales.Receipts; using Centron.Data.WebServices.Sales.Receipts.Invoices; using Centron.Data.WebServices.Sales.Receipts.Offers; using Centron.Interfaces; using Centron.Interfaces.Accounts; using Centron.Interfaces.Administration.Environment; using Centron.Interfaces.BL; using Centron.Interfaces.Sales.Receipts; using Centron.Interfaces.Sales.Receipts.InsertReceipts; using Centron.Tests.EndToEnd.Infrastructure; using CentronSoftware.Centron.WebServices.Entities.Sales.Receipts; using CentronSoftware.Centron.WebServices.Entities.Sales.Receipts.ContractLists; using CentronSoftware.Centron.WebServices.EntitiesWrongPlace.Sales.Receipts.DataAndResults; using CentronSoftware.Centron.WebServices.Extensions; using Xunit; using Xunit.Abstractions; namespace Centron.Tests.EndToEnd.Tests.ReceiptProvisions { public class ReceiptProvisionTests : EndToEndTest { public ReceiptProvisionTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } private const int CustomerNumber = 10020; private const int Offer1I3D = 6750; private const int Offer2I3D = 6748; private const int Offer3I3D = 6732; private const int Offer4I3D = 6728; private const int Offer5I3D = 6723; private const int Offer6I3D = 6716; public override void Execute() { this.CanNotCreateProvisionSchemaWithInvalidData(step:1); this.CreateNewSchema(step:2); this.LoadProvisionSchema(step:3); this.CanUseSchemaAsGlobal(step:4); this.CanAssignSchemaToCustomer(step:5); this.LoadProvisionSchemaCustomerAssignments(step:6); this.DeleteProvisionSchema(step:7); this.CanSaveReadAndDeleteReceiptProvisionItems(step: 8); this.CanSaveReceiptWithProvisionItems(step: 9); this.ProvisionIsCopiedWhenForwarding(step: 10); this.ApplySchemaToExistingOpenReceipts(step: 11); this.GetProvisionEvaluation(step: 12); this.ProvisionRightsExist(step: 13); this.CanNotSaveOrDeleteSchemaWithoutRights(step: 14); this.UpdateSchemaCustomerAssignments(step: 15); this.UpdateSchemaCustomerAssignmentWithoutRights(step: 16); this.FilterEmployeeI3DWorks(step: 17); this.GetReceiptsWithoutProvision(step: 18); this.ProvisionUpdatesWhenPurchasePriceChanges(step: 19); } private void CanNotCreateProvisionSchemaWithInvalidData(int step) { void ShouldThrowFor(ReceiptProvisionSchemaDTO schema, LoggedInUser currentUser) where T : Exception { using var session = new BLSession(); Assert.Throws(() => session.GetBL().SaveProvisionSchema(schema, currentUser)); } ShouldThrowFor(new ReceiptProvisionSchemaDTO { Name = null, //Error }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { Name = string.Empty, //Error }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { Name = " ", //Error }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { I3D = -1, //Error Name = "Something" }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { I3D = 0, Name = "Something", Items = null //Error }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { I3D = 0, Name = "Something", Items = { null //Error } }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { I3D = 0, Name = "Something", Items = { new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.ReceiptAdviser1, ProvisionPercentage = -10 //Error } } }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { I3D = 0, Name = "Something", Items = { new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.ReceiptAdviser1, SharePercentage = -10 //Error } } }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { I3D = 0, Name = "Something", Items = { new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.ReceiptAdviser1, Source = (ReceiptProvisionSource)123456, //Error } } }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { I3D = 0, Name = "Something", Items = { new ReceiptProvisionSchemaItemDTO { Receiver = (ReceiptProvisionReceiver)123456, //Error } } }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { I3D = 0, Name = "Something", Items = { new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.FixedEmployee, EmployeeI3D = null, //Error } } }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { I3D = 0, Name = "Something", Items = { new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.FixedEmployee, EmployeeI3D = 1, } } }, null); //Error (LoggedInUser currentUser is NULL) ShouldThrowFor(new ReceiptProvisionSchemaDTO { I3D = 0, Name = "Something", Items = { new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.FixedEmployee, EmployeeI3D = 1, Value = (ReceiptProvisionValue)123456, //Error } } }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { I3D = 0, Name = "Something", Items = { new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.FixedEmployee, EmployeeI3D = 1, Source = ReceiptProvisionSource.MaterialGroups, SourceMaterialGroups = null //Error } } }, this.GetLoggedInUser()); ShouldThrowFor(new ReceiptProvisionSchemaDTO { I3D = 0, Name = "Something", Items = { new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.FixedEmployee, EmployeeI3D = 1, Source = ReceiptProvisionSource.MaterialGroups, SourceMaterialGroups = new() //Error (empty list) } } }, this.GetLoggedInUser()); } private void CreateNewSchema(int step) { var schema = new ReceiptProvisionSchemaDTO { Name = "Globale Provision", Items = { new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.FixedEmployee, EmployeeI3D = 23, SharePercentage = 100, ProvisionPercentage = 10, Source = ReceiptProvisionSource.ServiceOnly, Value = ReceiptProvisionValue.Auto }, new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.CustomerAdviser1, EmployeeI3D = null, SharePercentage = 80, ProvisionPercentage = 5, Source = ReceiptProvisionSource.ServiceOnly, Value = ReceiptProvisionValue.Auto, Description = "Test-Test" }, new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.CustomerAdviser5, EmployeeI3D = null, SharePercentage = 20, ProvisionPercentage = 5, Source = ReceiptProvisionSource.ServiceOnly, Value = ReceiptProvisionValue.Auto, Description = "CustomerAdviser5" }, new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.ReceiptAdviser1, EmployeeI3D = null, SharePercentage = 100, ProvisionPercentage = 3, Source = ReceiptProvisionSource.MaterialGroups, SourceMaterialGroups = new List { new() { MaterialGroupI3D = 1, SubMaterialGroupI3D = null }, new() { MaterialGroupI3D = 2, SubMaterialGroupI3D = 10 }, }, Value = ReceiptProvisionValue.Auto, FilterEmployeeI3D = 10, } } }; using var session = new BLSession(); var saveResult1 = session.GetBL().SaveProvisionSchema(schema, this.GetLoggedInUser()); this.Verifier.Verify($"{step}_CreateNewSchema_1", saveResult1); var saveResult2 = session.GetBL().SaveProvisionSchema(schema, this.GetLoggedInUser()); this.Verifier.Verify($"{step}_CreateNewSchema_2", saveResult2); } private void LoadProvisionSchema(int step) { using var session = new BLSession(); var allSchemas = session.GetBL().GetAllProvisionSchemas(); this.Verifier.Verify($"{step}_AllSchemas", allSchemas); } private void CanUseSchemaAsGlobal(int step) { using var session = new BLSession(); var schema = session.GetBL().GetAllProvisionSchemas().First(); // Set up AutomHelpdesk test data using BL layer var settings = session.GetBL().GetReceiptSettings(this.GetLoggedInUser().User); settings.GlobalReceiptProvisionSchemaI3D = schema.I3D; settings.AutomHelpdeskAdditionalText1 = "Additional Text 1 for Test"; settings.AutomHelpdeskAdditionalText2 = "Additional Text 2 for Test"; settings.AutomHelpdeskOnlyInternal = true; settings.AutomHelpdeskPriority = 2; settings.AutomHelpdeskStatus = 1; settings.AutomHelpdeskSubCategory1 = 3; settings.AutomHelpdeskSubCategory2 = 5; settings.AutomHelpdeskProcessorI3Ds = "10"; settings.AutomHelpdeskResponsiblePersonI3D = 15; settings.AutomHelpdeskSendEmailToProcessor = true; settings.AutomHelpdeskCategoryI3D = 20; settings.AutomHelpdeskCreateSeparateTicketsMode = 1; settings.AutomHelpdeskOpenAfterwards = true; settings.AutomHelpdeskCreateTicketForAll = true; settings.AutomHelpdeskSelectedTemplateI3D = 25; session.GetBL().UpdateReceiptSettings(settings, this.GetLoggedInUser().User); this.Verifier.Verify($"{step}_ReceiptSettingsWithGlobalProvisionSchema", settings); // Ensure we get the global schema as a "current provision-schema for this customer" var schemaForCustomer = session.GetBL().GetCurrentProvisionSchemaForCustomer(CustomerNumber, null); Assert.Equal(schema.I3D, schemaForCustomer.I3D); // Ensure we get the correct provision-schema when creating a new receipt var receiptResult = session.GetBL().CreateNewReceipt( CentronObjectKindNumeric.OfferClass, this.GetLoggedInUser(), CustomerNumber, new CreateReceiptData { IgnoreCallbacks = true }, addressI3D: null, contactPersonI3D: null, insertSalutationAndAgreement: false, ignoreDefaultContract: true, insertCustomerDiscount: false).ThrowIfError(); var offer = (ReceiptOfferDTO)receiptResult.Receipt; this.Verifier.Verify($"{step}_ProvisionInNewReceipt", offer.Provision); } private void CanAssignSchemaToCustomer(int step) { using var session = new BLSession(); // The first one is the global one already, we wanna assign a different one to the customer, so we use .Last() var schema = session.GetBL().GetAllProvisionSchemas().Last(); var accountFilter = new AccountFilter { OldReference = new AccountFilterOldReference { Kind = AccountTypeKind.Customer, I3D = CustomerNumber } }; var account = session.GetBL().GetAccount(this.GetLoggedInUser(), accountFilter, false).ThrowIfError(); if (account.TryGetCustomerData(out var customerData)) { customerData.ProvisionSchemaI3D = schema.I3D; } session.GetBL().SaveAccount(this.GetLoggedInUser(), account, mixMode: false, isDataImport: false).ThrowIfError(); this.Verifier.VerifyTable($"{step}_AccountCustomerWithProvisionSchema", "AccountCustomers", $"Number = {CustomerNumber}"); // Ensure we get the customer-schema as a "current provision-schema for this customer" var schemaForCustomer = session.GetBL().GetCurrentProvisionSchemaForCustomer(CustomerNumber, null); Assert.Equal(schema.I3D, schemaForCustomer.I3D); // Ensure we get the correct provision-schema when creating a new receipt var receiptResult = session.GetBL().CreateNewReceipt( CentronObjectKindNumeric.OfferClass, this.GetLoggedInUser(), CustomerNumber, new CreateReceiptData { IgnoreCallbacks = true }, addressI3D: null, contactPersonI3D: null, insertSalutationAndAgreement: false, ignoreDefaultContract: true, insertCustomerDiscount: false).ThrowIfError(); var offer = (ReceiptOfferDTO)receiptResult.Receipt; this.Verifier.Verify($"{step}_ProvisionInNewReceipt", offer.Provision); } private void LoadProvisionSchemaCustomerAssignments(int step) { using var session = new BLSession(); var assignments = session.GetBL().GetAllProvisionSchemaDetails(); this.Verifier.Verify($"{step}_CustomerAssignments", assignments); } private void DeleteProvisionSchema(int step) { using var session = new BLSession(); session.GetBL().DeleteProvisionSchema(1, this.GetLoggedInUser()); session.GetBL().DeleteProvisionSchema(2, this.GetLoggedInUser()); this.Verifier.VerifyTable($"{step}_AccountCustomer_NoSchema", "AccountCustomers", $"Number = {CustomerNumber}"); this.Verifier.VerifyTable($"{step}_Schemas", "ReceiptProvisionSchemas"); this.Verifier.VerifyTable($"{step}_SchemaItems", "ReceiptProvisionSchemaItems"); // Ensure we get NULL as a "current provision-schema for this customer" var schemaForCustomer = session.GetBL().GetCurrentProvisionSchemaForCustomer(CustomerNumber, null); Assert.Null(schemaForCustomer); } private void CanSaveReadAndDeleteReceiptProvisionItems(int step) { using var session = new DAOSession(); var existingProvisionItems = session.GetGenericDAO().Query().ToList(); Assert.Empty(existingProvisionItems); var item = new ReceiptProvisionItemEntity { ReceiptI3D = 1, ReceiptKind = CentronObjectKindNumeric.OfferClass, Receiver = ReceiptProvisionReceiver.FixedEmployee, EmployeeI3D = 23, FilterEmployeeI3D = 11, SharePercentage = 60, ProvisionPercentage = 10, Source = ReceiptProvisionSource.All, Value = ReceiptProvisionValue.Auto, Description = "Another test description", ActualProvision = 100.50m, ActualPrice = 123.45m, ActualEmployeeI3D = 23 }; session.GetGenericDAO().SaveOrUpdate(item); Assert.NotEqual(0, item.I3D); this.Verifier.VerifyTable($"{step}_ReceiptProvisionItems_AfterInsert", "ReceiptProvisionItems"); session.GetGenericDAO().Delete(item); var provisionItemsAfterDelete = session.GetGenericDAO().Query().ToList(); this.Verifier.VerifyTable($"{step}_ReceiptProvisionItems_AfterDelete", "ReceiptProvisionItems"); } private void CanSaveReceiptWithProvisionItems(int step) { // We have to insert a provision-schema, to use the new structure // If there is none (as right now), then we will automatically fall back to the old provision structure using (var session = new BLSession()) { session.GetBL().SaveProvisionSchema(new ReceiptProvisionSchemaDTO { Name = "Test" }, this.GetLoggedInUser()); } var offerI3Ds = new List { Offer1I3D, Offer2I3D, Offer3I3D, Offer4I3D, Offer5I3D, Offer6I3D, }; foreach (var offerI3D in offerI3Ds) { ReceiptOfferDTO offer; // Create new version using (var session = new BLSession()) { var newVersion = session.GetBL().CreateNewVersion( CentronObjectKindNumeric.OfferClass, offerI3D, version: null, newContactPersonI3D: null, this.GetLoggedInUser().User, new CreateNewVersionData { IgnoreCallbacks = true, }).ThrowIfError(); offer = (ReceiptOfferDTO)newVersion.Receipt; } // Set provision offer.Provision = new List { new() { Receiver = ReceiptProvisionReceiver.CustomerAdviser1, EmployeeI3D = null, SharePercentage = 100, ProvisionPercentage = 20.0m, Source = ReceiptProvisionSource.ProductsOnly, Value = ReceiptProvisionValue.Earnings, FilterEmployeeI3D = 34, }, new() { Receiver = ReceiptProvisionReceiver.FixedEmployee, EmployeeI3D = 10, SharePercentage = 80, ProvisionPercentage = 30.0m, Source = ReceiptProvisionSource.ServiceOnly, Value = ReceiptProvisionValue.Sales, Description = "Some description" }, new() { Receiver = ReceiptProvisionReceiver.FixedEmployee, EmployeeI3D = 12, SharePercentage = 100, ProvisionPercentage = 100, Value = ReceiptProvisionValue.Sales, Source = ReceiptProvisionSource.MaterialGroups, SourceMaterialGroups = new List { new () { MaterialGroupI3D = 1, SubMaterialGroupI3D = null, }, // Hardware new () { MaterialGroupI3D = 1, SubMaterialGroupI3D = 10, }, // Hardware -> Monitore } } }; // Save receipt using (var session = new BLSession()) { var saveResult = session.GetBL().SaveReceipt( offer, this.GetLoggedInUser().User, new SaveReceiptData { IgnoreCallbacks = true }, autoLockIfNewReceipt: false, CreatedThroughApplication.WebServices, receiptTemplateFolderI3D: 0).ThrowIfError(); } // Verify provision this.Verifier.VerifyTable($"{step}_Offer_{offerI3D}_WithProvision", "ReceiptProvisionItems", $"ReceiptI3D = {offerI3D} AND ReceiptKind = 1"); } } private void ProvisionIsCopiedWhenForwarding(int step) { using var session = new BLSession(); var forwardResult = session.GetBL().ForwardReceipt( CentronObjectKindNumeric.InvoiceClass, this.GetLoggedInUser().User, new ForwardReceiptData { IgnoreCallbacks = true, CreateReceiptData = new CreateReceiptData { IgnoreCallbacks = true, }, CreateReceiptItemsFromExistingItemsData = new List { new() { IgnoreCallbacks = true, }, }, }, new List { new() { ReceiptKind = CentronObjectKindNumeric.OfferClass, ReceiptI3D = Offer1I3D, } }, receiptProjectLayoutItemI3DsToForward: null, InsertReceiptTakeoverOptions.Reference, onlyTakeoverAvailableQuantity: true, ignoreDefaultContract: true).ThrowIfError(); var invoice = (ReceiptInvoiceDTO)forwardResult.Receipt; this.Verifier.Verify($"{step}_ProvisionAfterForwarding", invoice.Provision); } private void ApplySchemaToExistingOpenReceipts(int step) { using (var session = new BLSession()) { // Create new schema var schema = session.GetBL().SaveProvisionSchema(new ReceiptProvisionSchemaDTO { Name = "Globales-Schema", Items = new List { new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.CustomerAdviser2, SharePercentage = 90, ProvisionPercentage = 10, Source = ReceiptProvisionSource.All, Description = "Hibbety Hoppety - DESCRIPTION!", Value = ReceiptProvisionValue.Auto } } }, this.GetLoggedInUser()); // Set it as global var settings = session.GetBL().GetReceiptSettings(this.GetLoggedInUser().User); settings.GlobalReceiptProvisionSchemaI3D = schema.I3D; session.GetBL().UpdateReceiptSettings(settings, this.GetLoggedInUser().User); } Test("Offers_Invoices_Open", new List { CentronObjectKindNumeric.OfferClass, CentronObjectKindNumeric.InvoiceClass }, includeClosedReceipts:false, forceOverwriteProvision:false, from: null, to: null, branchI3Ds: null); Test("Offers_Invoices_Open_Again", new List { CentronObjectKindNumeric.OfferClass, CentronObjectKindNumeric.InvoiceClass }, includeClosedReceipts:false, forceOverwriteProvision:false, from: null, to: null, branchI3Ds: null); Test("Offers_Invoices_Open_Overwrite", new List { CentronObjectKindNumeric.OfferClass, CentronObjectKindNumeric.InvoiceClass }, includeClosedReceipts:false, forceOverwriteProvision:true, from: null, to: null, branchI3Ds: null); Test("Offers_Invoices_Open_DateTo", new List { CentronObjectKindNumeric.OfferClass, CentronObjectKindNumeric.InvoiceClass }, includeClosedReceipts:false, forceOverwriteProvision:true, from: null, to: new DateTime(2017, 6, 30), branchI3Ds: null); this.Verifier.VerifyTable($"{step}_ReceiptProvisionItems", "ReceiptProvisionItems"); void Test(string name, List receiptKinds, bool includeClosedReceipts, bool forceOverwriteProvision, DateTime? from, DateTime? to, List branchI3Ds) { List alreadyUpdatedReceipts = null; while (true) { using (var session = new BLSession()) { int? previousCount = alreadyUpdatedReceipts?.Count; alreadyUpdatedReceipts = session.GetBL().ApplyCurrentSchemaToOpenReceiptsWithoutProvision( receiptKinds, null, includeClosedReceipts, forceOverwriteProvision, from, to, branchI3Ds, alreadyUpdatedReceipts, this.GetLoggedInUser(), receiptsToUpdateCount:10); //Use a smaller count so we can test the "call the method again" workflow // We didn't get any new receipts, that means we are done if (previousCount == alreadyUpdatedReceipts.Count) break; } } this.Verifier.Verify($"{step}_ApplyCurrentSchemaToReceipts_{name}", alreadyUpdatedReceipts); } } private void GetProvisionEvaluation(int step) { // One invoice should have a receipt-user-state, so we can check the filtering for it this.Sql("UPDATE dbo.RechKopf SET ReceiptUserStateI3D = 1 WHERE I3D = 1330"); // And one should be closed this.Sql("UPDATE dbo.RechKopf SET Status = 2 WHERE I3D = 1347"); // And we need some receipt with 0 provision this.Sql("UPDATE dbo.ReceiptProvisionItems SET ActualProvision = 0, ActualProvisionSales = NULL, ActualProvisionEarnings = NULL WHERE ReceiptI3D = 6420 AND ReceiptKind = 4"); RunTest("All", new ReceiptProvisionEvaluationFilter(), this.GetLoggedInUser()); RunTest("DateStart", new ReceiptProvisionEvaluationFilter { DateStart = new DateTime(2017, 3, 1)}, this.GetLoggedInUser()); RunTest("DateEnd", new ReceiptProvisionEvaluationFilter { DateEnd = new DateTime(2017, 4, 1)}, this.GetLoggedInUser()); RunTest("ReceiptUserState", new ReceiptProvisionEvaluationFilter { ReceiptUserStateI3D = 1 }, this.GetLoggedInUser()); RunTest("OnlyClosedReceipts", new ReceiptProvisionEvaluationFilter { OnlyClosedReceipts = true }, this.GetLoggedInUser()); RunTest("OnlyOwn", new ReceiptProvisionEvaluationFilter { OnlyOwn = true }, this.GetLoggedInUser(userI3D: 16)); //AppUser 16 is Employee 27 RunTest("IncludeZeroProvision_Before", new ReceiptProvisionEvaluationFilter { DateStart = new DateTime(2017, 6, 26), DateEnd = new DateTime(2017, 6, 26), IncludeZeroProvisions = false}, this.GetLoggedInUser()); RunTest("IncludeZeroProvision_After", new ReceiptProvisionEvaluationFilter { DateStart = new DateTime(2017, 6, 26), DateEnd = new DateTime(2017, 6, 26), IncludeZeroProvisions = true}, this.GetLoggedInUser()); RunRightsTests(); void RunTest(string name, ReceiptProvisionEvaluationFilter filter, LoggedInUser currentUser) { using var session = new BLSession(); var evaluations = session.GetBL().GetProvisionEvaluation(filter, currentUser); this.Verifier.Verify($"{step}_{name}", evaluations); // Ensure that all the price and provision fields add up Assert.All(evaluations, f => { Assert.Equal(f.Price, f.PriceSales.GetValueOrDefault() + f.PriceEarnings.GetValueOrDefault()); Assert.Equal(f.Provision, f.ProvisionSales.GetValueOrDefault() + f.ProvisionEarnings.GetValueOrDefault()); }); } void RunRightsTests() { const int UserI3DWithoutRight = 26; // First, remove the User 26 from the administrator right-group this.Sql($"DELETE FROM dbo.Sichmemb WHERE Gruppe = 6 AND Benutzer = {UserI3DWithoutRight}"); // Throws if you don't have the right var exception = Assert.Throws(() => { RunTest("Rights_NoRight", new ReceiptProvisionEvaluationFilter(), this.GetLoggedInUser(UserI3DWithoutRight)); }); this.Verifier.Verify($"{step}_Rights_NoRight_Exception", new { exception.Message, exception.MessageCode }); // Now add the right to a group this.Sql($"INSERT INTO dbo.Sichtrus (Gruppe, Recht) VALUES (15, {UserRightsConst.Sales.Provision.PROVISION_EVALUATION_MODULE})"); // You should get all now RunTest("Rights_All", new ReceiptProvisionEvaluationFilter(), this.GetLoggedInUser(UserI3DWithoutRight)); // And add the "only-own" right this.Sql($"INSERT INTO dbo.Sichtrus (Gruppe, Recht) VALUES (15, {UserRightsConst.Sales.Provision.PROVISION_EVALUATION_ONLY_OWN})"); // You should get only your own now RunTest("Rights_OnlyOwn", new ReceiptProvisionEvaluationFilter(), this.GetLoggedInUser(UserI3DWithoutRight)); } } private void ProvisionRightsExist(int step) { var provisionRights = new[] { UserRightsConst.Sales.Provision.ID, UserRightsConst.Sales.Provision.PROVISION_EVALUATION_MODULE, UserRightsConst.Sales.Provision.PROVISION_EVALUATION_ONLY_OWN, UserRightsConst.Sales.Provision.PROVISION_SCHEMA_MANAGEMENT, UserRightsConst.Sales.Provision.PROVISION_SCHEMA_CUSTOMER_ASSIGNMENT, }; using var session = new BLSession(); var allRights = session.GetBL().GetAllRights().ThrowIfError(); var foundRights = allRights.Where(f => provisionRights.Contains(f.I3D)).ToList(); this.Verifier.Verify($"{step}_Provision_Rights", foundRights); } private void CanNotSaveOrDeleteSchemaWithoutRights(int step) { using var session = new BLSession(); // Load current user var currentUser = new LoggedInUser(session.GetBL().GetAppUser(f => f.I3D == 20)); var currentUserHasRight = session.GetBL().HasUserRight(currentUser.UserI3D.Value, UserRightsConst.Sales.Provision.PROVISION_SCHEMA_MANAGEMENT); Assert.False(currentUserHasRight); // And make sure he doesn't have the needed right // Save new Schema / Update schema var exception = Assert.Throws(() => { using var testSession = new BLSession(); testSession.GetBL().SaveProvisionSchema(new ReceiptProvisionSchemaDTO { Name = "Test-Schema that can't be saved anyways", Items = new List { new ReceiptProvisionSchemaItemDTO { Receiver = ReceiptProvisionReceiver.FixedEmployee, EmployeeI3D = 1 } } }, currentUser); }); this.Verifier.Verify($"{step}_SaveProvisionSchema_RightMissingException", new { exception.Message, exception.MessageCode }); // Delete existing schema var existingSchemaI3D = session.GetBL().GetAllProvisionSchemas().First().I3D; exception = Assert.Throws(() => { using var testSession = new BLSession(); testSession.GetBL().DeleteProvisionSchema(existingSchemaI3D, currentUser); }); this.Verifier.Verify($"{step}_DeleteProvisionSchema_RightMissingException", new { exception.Message, exception.MessageCode }); } private void UpdateSchemaCustomerAssignments(int step) { using (var session = new BLSession()) { var detailsBefore = session.GetBL().GetAllProvisionSchemaDetails(); this.Verifier.Verify($"{step}_ProvisionSchemaDetails_Before", detailsBefore); } using (var session = new BLSession()) { // Assign schema 3 to customer 10011, and NULL to all other customers var assignments = new List { new ReceiptProvisionSchemaDetailsDTO { SchemaI3D = 3, CustomerAssignments = new List { new ReceiptProvisionSchemaCustomerAssignmentDTO { CustomerNumber = 10011 }, new ReceiptProvisionSchemaCustomerAssignmentDTO { CustomerNumber = 10011, BranchI3D = 0 }, new ReceiptProvisionSchemaCustomerAssignmentDTO { CustomerNumber = 10012, BranchI3D = 1 } } } }; session.GetBL().UpdateProvisionSchemaCustomerAssignments(assignments, this.GetLoggedInUser()); } using (var session = new BLSession()) { var detailsAfter = session.GetBL().GetAllProvisionSchemaDetails(); this.Verifier.Verify($"{step}_ProvisionSchemaDetails_After", detailsAfter); this.Verifier.VerifySql($"{step}_AccountCustomersTable", "SELECT AC.Number, AC.ProvisionSchemaI3D FROM dbo.AccountCustomers AC"); this.Verifier.VerifyTable($"{step}_ReceiptProvisionSchemaCustomerAssignments", "ReceiptProvisionSchemaCustomerAssignments"); } } private void UpdateSchemaCustomerAssignmentWithoutRights(int step) { using var session = new BLSession(); // Load current user var currentUser = new LoggedInUser(session.GetBL().GetAppUser(f => f.I3D == 20)); var currentUserHasRight = session.GetBL().HasUserRight(currentUser.UserI3D.Value, UserRightsConst.Sales.Provision.PROVISION_SCHEMA_CUSTOMER_ASSIGNMENT); Assert.False(currentUserHasRight); // And make sure he doesn't have the needed right // Save new Schema / Update schema var exception = Assert.Throws(() => { using var testSession = new BLSession(); testSession.GetBL().UpdateProvisionSchemaCustomerAssignments(new List(), currentUser); }); this.Verifier.Verify($"{step}_UpdateProvisionSchemaCustomerAssignments_RightMissingException", new { exception.Message, exception.MessageCode }); } private void FilterEmployeeI3DWorks(int step) { Test("BothProvisions", Offer1I3D, null, null); Test("OnlyFirstProvision", Offer1I3D, 34, 60); Test("OnlyFirstProvision_SecondSkipped", Offer1I3D, 34, null); Test("OnlySecondProvision", Offer1I3D, 35, null); void Test(string name, int offerI3D, int? filterEmployeeI3D, int? secondFilterEmployeeI3D) { ReceiptOfferDTO offer; // Create new version using (var session = new BLSession()) { var newVersion = session.GetBL().CreateNewVersion( CentronObjectKindNumeric.OfferClass, offerI3D, version: null, newContactPersonI3D: null, this.GetLoggedInUser().User, new CreateNewVersionData { IgnoreCallbacks = true, }).ThrowIfError(); offer = (ReceiptOfferDTO)newVersion.Receipt; } // Set provision offer.Provision = new List { new() { Receiver = ReceiptProvisionReceiver.CustomerAdviser1, EmployeeI3D = null, SharePercentage = 100, ProvisionPercentage = 100.0m, Source = ReceiptProvisionSource.ProductsOnly, Value = ReceiptProvisionValue.Earnings, FilterEmployeeI3D = filterEmployeeI3D, }, new() { Receiver = ReceiptProvisionReceiver.CustomerAdviser1, EmployeeI3D = null, SharePercentage = 100, ProvisionPercentage = 100.0m, Source = ReceiptProvisionSource.ProductsOnly, Value = ReceiptProvisionValue.Earnings, FilterEmployeeI3D = secondFilterEmployeeI3D, } }; // Save receipt using (var session = new BLSession()) { var saveResult = session.GetBL().SaveReceipt( offer, this.GetLoggedInUser().User, new SaveReceiptData { IgnoreCallbacks = true }, autoLockIfNewReceipt: false, CreatedThroughApplication.WebServices, receiptTemplateFolderI3D: 0).ThrowIfError(); } // Verify provision this.Verifier.VerifyTable($"{step}_Offer_{offerI3D}_{name}", "ReceiptProvisionItems", $"ReceiptI3D = {offerI3D} AND ReceiptKind = 1"); } } private void GetReceiptsWithoutProvision(int step) { using var session = new BLSession(); var filter = new ReceiptWithoutProvisionFilter { DateStart = null, DateEnd = null }; var receiptsWithoutProvision = session.GetBL().GetReceiptsWithoutProvision(filter, this.GetLoggedInUser()); this.Verifier.Verify($"{step}_ReceiptsWithoutProvision", receiptsWithoutProvision); } private void ProvisionUpdatesWhenPurchasePriceChanges(int step) { using var session = new BLSession(); var itemI3D = 21318; var newPurchasePrice = 10; // Update the purchase-price of this item // That should force a recalculation of the provision session.GetBL().UpdateReceiptItemPurchasePrice( this.GetLoggedInUser().User, CentronObjectKindNumeric.OfferClass, Offer1I3D, itemI3D, null, newPurchasePrice).ThrowIfError(); // Verify provision this.Verifier.VerifyTable($"{step}_Offer", "ReceiptProvisionItems", $"ReceiptI3D = {Offer1I3D} AND ReceiptKind = 1"); } } }