public void GivenWorkEffortAndTimeEntry_WhenDeriving_ThenWorkEffortPartyAssignmentSynced()
        {
            // Arrange
            var workOrder  = new WorkTaskBuilder(this.Session).WithName("Task").Build();
            var employee   = new PersonBuilder(this.Session).WithFirstName("Good").WithLastName("Worker").Build();
            var employment = new EmploymentBuilder(this.Session).WithEmployee(employee).Build();

            this.Session.Derive(true);

            var today    = DateTimeFactory.CreateDateTime(DateTime.UtcNow);
            var tomorrow = DateTimeFactory.CreateDateTime(DateTime.UtcNow.AddDays(1));
            var hour     = new TimeFrequencies(this.Session).Hour;

            var timeEntry = new TimeEntryBuilder(this.Session)
                            .WithRateType(new RateTypes(this.Session).StandardRate)
                            .WithFromDate(today)
                            .WithThroughDate(tomorrow)
                            .WithTimeFrequency(hour)
                            .WithWorkEffort(workOrder)
                            .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntry);

            // Act
            this.Session.Derive(true);

            // Assert
            var partyAssignment = workOrder.WorkEffortPartyAssignmentsWhereAssignment.First;

            Assert.Equal(workOrder, partyAssignment.Assignment);
            Assert.Equal(employee, partyAssignment.Party);
            Assert.False(partyAssignment.ExistFromDate);
            Assert.False(partyAssignment.ExistThroughDate);
        }
        public void GivenTimeEntryWithFromAndThroughDates_WhenDeriving_ThenAmountOfTimeDerived()
        {
            // Arrange
            var frequencies = new TimeFrequencies(this.Session);

            var customer             = new OrganisationBuilder(this.Session).WithName("Org1").Build();
            var internalOrganisation = new Organisations(this.Session).Extent().First(o => o.IsInternalOrganisation);

            new CustomerRelationshipBuilder(this.Session).WithCustomer(customer).WithInternalOrganisation(internalOrganisation).Build();

            var workOrder = new WorkTaskBuilder(this.Session).WithName("Task").WithCustomer(customer).WithTakenBy(internalOrganisation).Build();
            var employee  = new PersonBuilder(this.Session).WithFirstName("Good").WithLastName("Worker").Build();

            new EmploymentBuilder(this.Session).WithEmployee(employee).WithEmployer(internalOrganisation).Build();

            this.Session.Derive(true);

            var now   = DateTimeFactory.CreateDateTime(this.Session.Now());
            var later = DateTimeFactory.CreateDateTime(now.AddHours(4));

            var timeEntry = new TimeEntryBuilder(this.Session)
                            .WithRateType(new RateTypes(this.Session).StandardRate)
                            .WithFromDate(now)
                            .WithThroughDate(later)
                            .WithTimeFrequency(frequencies.Hour)
                            .WithWorkEffort(workOrder)
                            .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntry);

            // Act
            this.Session.Derive(true);

            // Assert
            Assert.Equal(4.00M, timeEntry.AmountOfTime);
            Assert.Equal(4.00M, timeEntry.ActualHours);

            //// Re-arrange
            ((TimeEntryDerivedRoles)timeEntry).RemoveAmountOfTime();
            timeEntry.TimeFrequency = frequencies.Day;

            // Act
            this.Session.Derive(true);

            // Assert
            Assert.Equal(Math.Round(4.0M / 24.0M, M.TimeEntry.AmountOfTime.Scale ?? 2), timeEntry.AmountOfTime);
            Assert.Equal(4.00M, timeEntry.ActualHours);

            //// Re-arrange
            ((TimeEntryDerivedRoles)timeEntry).RemoveAmountOfTime();
            timeEntry.TimeFrequency = frequencies.Minute;

            // Act
            this.Session.Derive(true);

            // Assert
            Assert.Equal(4.0M * 60.0M, timeEntry.AmountOfTime);
            Assert.Equal(4.00M, timeEntry.ActualHours);
        }
示例#3
0
        public void GivenTimeEntryWithFromDateAndAmountOfTime_WhenDeriving_ThenThroughDateDerived()
        {
            // Arrange
            var frequencies = new TimeFrequencies(this.Session);
            var workOrder   = new WorkTaskBuilder(this.Session).WithName("Task").Build();
            var employee    = new PersonBuilder(this.Session).WithFirstName("Good").WithLastName("Worker").Build();
            var employment  = new EmploymentBuilder(this.Session).WithEmployee(employee).Build();

            this.Session.Derive(true);

            var now  = DateTimeFactory.CreateDateTime(this.Session.Now());
            var hour = frequencies.Hour;

            var timeEntry = new TimeEntryBuilder(this.Session)
                            .WithRateType(new RateTypes(this.Session).StandardRate)
                            .WithFromDate(now)
                            .WithAmountOfTime(4.0M)
                            .WithTimeFrequency(hour)
                            .WithWorkEffort(workOrder)
                            .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntry);

            // Act
            this.Session.Derive(true);

            // Assert
            var timeSpan = timeEntry.ThroughDate - timeEntry.FromDate;

            Assert.Equal(4.00, timeSpan.Value.TotalHours);
            Assert.Equal(4.0M, timeEntry.ActualHours);

            //// Re-arrange
            timeEntry.RemoveThroughDate();
            timeEntry.TimeFrequency = frequencies.Minute;

            // Act
            this.Session.Derive(true);

            // Assert
            timeSpan = timeEntry.ThroughDate - timeEntry.FromDate;
            Assert.Equal(4.00, timeSpan.Value.TotalMinutes);
            Assert.Equal(Math.Round(4.0M / 60.0M, M.TimeEntry.AmountOfTime.Scale ?? 2), timeEntry.ActualHours);

            //// Re-arrange
            timeEntry.RemoveThroughDate();
            timeEntry.TimeFrequency = frequencies.Day;

            // Act
            this.Session.Derive(true);

            // Assert
            timeSpan = timeEntry.ThroughDate - timeEntry.FromDate;
            Assert.Equal(4.00, timeSpan.Value.TotalDays);
            Assert.Equal(4.00M * 24.00M, timeEntry.ActualHours);
        }
示例#4
0
        public void AppsOnDerive(ObjectOnDerive method)
        {
            var derivation = method.Derivation;

            derivation.Validation.AssertExists(this, this.Meta.TimeSheetWhereTimeEntry);
            derivation.Validation.AssertAtLeastOne(this, this.Meta.WorkEffort, this.Meta.EngagementItem);
            derivation.Validation.AssertAtLeastOne(this, this.Meta.ThroughDate, this.Meta.AmountOfTime);

            if (this.ExistBillingRate)
            {
                derivation.Validation.AssertExists(this, this.Meta.BillingFrequency);
            }

            if (this.ExistAmountOfTime)
            {
                derivation.Validation.AssertExists(this, this.Meta.TimeFrequency);
            }

            if (this.ExistTimeSheetWhereTimeEntry)
            {
                this.Worker = this.TimeSheetWhereTimeEntry.Worker;
            }

            // calculate AmountOfTime Or ThroughDate
            var frequencies = new TimeFrequencies(this.strategy.Session);

            if (this.ThroughDate != null)
            {
                var timeSpan = this.ThroughDate - this.FromDate;
                var minutes  = (decimal)timeSpan.Value.TotalMinutes;
                var amount   = frequencies.Minute.ConvertToFrequency(minutes, this.TimeFrequency);

                if (amount == null)
                {
                    this.RemoveAmountOfTime();
                }
                else
                {
                    this.AmountOfTime = Math.Round((decimal)amount, 2);
                }
            }
            else if (this.AmountOfTime != null)
            {
                var minutes = this.TimeFrequency.ConvertToFrequency((decimal)this.AmountOfTime, frequencies.Minute);

                if (minutes == null)
                {
                    this.RemoveThroughDate();
                }
                else
                {
                    var timeSpan = TimeSpan.FromMinutes((double)minutes);
                    this.ThroughDate = new DateTime(this.FromDate.Ticks, this.FromDate.Kind) + timeSpan;
                }
            }
        }
示例#5
0
        public void GivenTimeEntryWithRequiredAssignmentOrganisation_WhenDeriving_ThenWorkEffortPartyAssignmentSynced()
        {
            // Arrange
            var customer             = new OrganisationBuilder(this.Session).WithName("Org1").Build();
            var internalOrganisation = new Organisations(this.Session).Extent().First(o => o.IsInternalOrganisation);

            new CustomerRelationshipBuilder(this.Session).WithCustomer(customer).WithInternalOrganisation(internalOrganisation).Build();

            var workOrder = new WorkTaskBuilder(this.Session).WithName("Task").WithCustomer(customer).WithTakenBy(internalOrganisation).Build();

            var employee = new PersonBuilder(this.Session).WithFirstName("Good").WithLastName("Worker").Build();

            new EmploymentBuilder(this.Session).WithEmployee(employee).WithEmployer(internalOrganisation).Build();

            internalOrganisation.RequireExistingWorkEffortPartyAssignment = true;
            this.Session.Derive(true);

            var today    = DateTimeFactory.CreateDateTime(this.Session.Now());
            var tomorrow = DateTimeFactory.CreateDateTime(this.Session.Now().AddDays(1));
            var hour     = new TimeFrequencies(this.Session).Hour;

            var timeEntry = new TimeEntryBuilder(this.Session)
                            .WithRateType(new RateTypes(this.Session).StandardRate)
                            .WithFromDate(today)
                            .WithThroughDate(tomorrow)
                            .WithTimeFrequency(hour)
                            .WithWorkEffort(workOrder)
                            .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntry);

            // Act
            var derivation = this.Session.Derive(false);

            // Assert
            Assert.True(derivation.HasErrors);
            Assert.Contains(derivation.Errors.SelectMany(e => e.Relations), r => r.AssociationType.Equals(M.WorkEffort.WorkEffortPartyAssignmentsWhereAssignment));

            //// Re-Arrange
            employee.TimeSheetWhereWorker.RemoveTimeEntries();

            var assignment = new WorkEffortPartyAssignmentBuilder(this.Session)
                             .WithAssignment(workOrder)
                             .WithParty(employee)
                             .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntry);

            // Act
            derivation = this.Session.Derive(false);

            // Assert
            Assert.False(derivation.HasErrors);
        }
示例#6
0
        public void GivenWorkEffortAndTimeEntries_WhenDeriving_ThenActualHoursDerived()
        {
            // Arrange
            var frequencies = new TimeFrequencies(this.Session);

            var workOrder  = new WorkTaskBuilder(this.Session).WithName("Task").Build();
            var employee   = new PersonBuilder(this.Session).WithFirstName("Good").WithLastName("Worker").Build();
            var employment = new EmploymentBuilder(this.Session).WithEmployee(employee).Build();

            this.Session.Derive(true);

            var yesterday      = DateTimeFactory.CreateDateTime(this.Session.Now().AddDays(-1));
            var laterYesterday = DateTimeFactory.CreateDateTime(yesterday.AddHours(3));

            var today      = DateTimeFactory.CreateDateTime(this.Session.Now());
            var laterToday = DateTimeFactory.CreateDateTime(today.AddHours(4));

            var tomorrow      = DateTimeFactory.CreateDateTime(this.Session.Now().AddDays(1));
            var laterTomorrow = DateTimeFactory.CreateDateTime(tomorrow.AddHours(6));

            var timeEntry1 = new TimeEntryBuilder(this.Session)
                             .WithRateType(new RateTypes(this.Session).StandardRate)
                             .WithFromDate(yesterday)
                             .WithThroughDate(laterYesterday)
                             .WithWorkEffort(workOrder)
                             .Build();

            var timeEntry2 = new TimeEntryBuilder(this.Session)
                             .WithRateType(new RateTypes(this.Session).StandardRate)
                             .WithFromDate(today)
                             .WithThroughDate(laterToday)
                             .WithWorkEffort(workOrder)
                             .Build();

            var timeEntry3 = new TimeEntryBuilder(this.Session)
                             .WithRateType(new RateTypes(this.Session).StandardRate)
                             .WithFromDate(tomorrow)
                             .WithThroughDate(laterTomorrow)
                             .WithWorkEffort(workOrder)
                             .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntry1);
            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntry2);
            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntry3);

            // Act
            this.Session.Derive(true);

            // Assert
            Assert.Equal(13.0M, workOrder.ActualHours);
        }
        public void Repeat()
        {
            var now     = this.Strategy.Session.Now().Date;
            var monthly = new TimeFrequencies(this.Strategy.Session).Month;
            var weekly  = new TimeFrequencies(this.Strategy.Session).Week;

            if (this.Frequency.Equals(monthly))
            {
                var nextDate = now.AddMonths(1).Date;
                this.Repeat(now, nextDate);
            }

            if (this.Frequency.Equals(weekly))
            {
                var nextDate = now.AddDays(7).Date;
                this.Repeat(now, nextDate);
            }
        }
示例#8
0
        public void GivenWorkEffortAndTimeEntriesWithoutBillingRate_WhenInvoiced_ThenWorkEffortRateIsUsed()
        {
            var frequencies = new TimeFrequencies(this.Session);

            var organisation = new Organisations(this.Session).Extent().First(o => o.IsInternalOrganisation);
            var customer     = new PersonBuilder(this.Session).WithLastName("Customer").Build();

            new CustomerRelationshipBuilder(this.Session).WithCustomer(customer).WithInternalOrganisation(organisation).Build();
            var employee = new PersonBuilder(this.Session).WithFirstName("Good").WithLastName("Worker").Build();

            new EmploymentBuilder(this.Session).WithEmployee(employee).WithEmployer(organisation).Build();

            var workOrder = new WorkTaskBuilder(this.Session).WithName("Task").WithCustomer(customer).Build();

            new WorkEffortAssignmentRateBuilder(this.Session).WithWorkEffort(workOrder).WithRate(10).WithRateType(new RateTypes(this.Session).StandardRate).Build();

            this.Session.Derive(true);

            var yesterday      = DateTimeFactory.CreateDateTime(this.Session.Now().AddDays(-1));
            var laterYesterday = DateTimeFactory.CreateDateTime(yesterday.AddHours(3));

            var today      = DateTimeFactory.CreateDateTime(this.Session.Now());
            var laterToday = DateTimeFactory.CreateDateTime(today.AddHours(4));

            var tomorrow      = DateTimeFactory.CreateDateTime(this.Session.Now().AddDays(1));
            var laterTomorrow = DateTimeFactory.CreateDateTime(tomorrow.AddHours(6));

            var timeEntryYesterday = new TimeEntryBuilder(this.Session)
                                     .WithRateType(new RateTypes(this.Session).StandardRate)
                                     .WithFromDate(yesterday)
                                     .WithThroughDate(laterYesterday)
                                     .WithWorkEffort(workOrder)
                                     .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntryYesterday);

            var timeEntryToday = new TimeEntryBuilder(this.Session)
                                 .WithRateType(new RateTypes(this.Session).StandardRate)
                                 .WithFromDate(today)
                                 .WithThroughDate(laterToday)
                                 .WithWorkEffort(workOrder)
                                 .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntryToday);

            var timeEntryTomorrow = new TimeEntryBuilder(this.Session)
                                    .WithRateType(new RateTypes(this.Session).StandardRate)
                                    .WithFromDate(tomorrow)
                                    .WithThroughDate(laterTomorrow)
                                    .WithTimeFrequency(frequencies.Minute)
                                    .WithWorkEffort(workOrder)
                                    .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntryTomorrow);

            workOrder.Complete();

            this.Session.Derive(true);

            workOrder.Invoice();

            var salesInvoice = customer.SalesInvoicesWhereBillToCustomer.First;

            Assert.Single(salesInvoice.InvoiceItems);
            Assert.Equal(130, salesInvoice.InvoiceItems.First().ActualUnitPrice); // (3 * 10) + (4 * 10) + (6 * 10)
        }
示例#9
0
        public void GivenWorkEffortPrintDocument_WhenPrinting_ThenMediaCreated()
        {
            // Arrange
            var frequencies = new TimeFrequencies(this.Session);
            var purposes    = new ContactMechanismPurposes(this.Session);

            //// Customer Contact and Address Data
            var customer         = new OrganisationBuilder(this.Session).WithName("Customer").Build();
            var customerContact  = new PersonBuilder(this.Session).WithFirstName("Customer").WithLastName("Contact").Build();
            var organisation     = new Organisations(this.Session).Extent().First(o => o.IsInternalOrganisation);
            var customerRelation = new CustomerRelationshipBuilder(this.Session).WithCustomer(customer).WithInternalOrganisation(organisation).Build();

            var usa             = new Countries(this.Session).Extent().First(c => c.IsoCode.Equals("US"));
            var michigan        = new StateBuilder(this.Session).WithName("Michigan").WithCountry(usa).Build();
            var northville      = new CityBuilder(this.Session).WithName("Northville").WithState(michigan).Build();
            var postalCode      = new PostalCodeBuilder(this.Session).WithCode("48167").Build();
            var billingAddress  = this.CreatePostalAddress("Billing Address", "123 Street", "Suite S1", northville, postalCode);
            var shippingAddress = this.CreatePostalAddress("Shipping Address", "123 Street", "Dock D1", northville, postalCode);
            var phone           = new TelecommunicationsNumberBuilder(this.Session).WithCountryCode("1").WithAreaCode("616").WithContactNumber("774-2000").Build();

            customer.AddPartyContactMechanism(this.CreatePartyContactMechanism(purposes.BillingAddress, billingAddress));
            customer.AddPartyContactMechanism(this.CreatePartyContactMechanism(purposes.ShippingAddress, shippingAddress));
            customerContact.AddPartyContactMechanism(this.CreatePartyContactMechanism(purposes.GeneralPhoneNumber, phone));

            //// Work Effort Data
            var salesPerson      = new PersonBuilder(this.Session).WithFirstName("Sales").WithLastName("Person").Build();
            var salesRepRelation = new SalesRepRelationshipBuilder(this.Session).WithCustomer(customer).WithSalesRepresentative(salesPerson).Build();
            var salesOrder       = this.CreateSalesOrder(customer, organisation);
            var workOrder        = this.CreateWorkEffort(organisation, customer, customerContact, salesOrder.SalesOrderItems.First);
            var employee         = new PersonBuilder(this.Session).WithFirstName("Good").WithLastName("Worker").Build();
            var employment       = new EmploymentBuilder(this.Session).WithEmployee(employee).WithEmployer(organisation).Build();

            var salesOrderItem = salesOrder.SalesOrderItems.First;

            salesOrder.AddValidOrderItem(salesOrderItem);

            //// Work Effort Inventory Assignmets
            var part1 = this.CreatePart("P1");
            var part2 = this.CreatePart("P2");
            var part3 = this.CreatePart("P3");

            this.Session.Derive(true);

            var inventoryAssignment1 = this.CreateInventoryAssignment(workOrder, part1, 11);
            var inventoryAssignment2 = this.CreateInventoryAssignment(workOrder, part2, 12);
            var inventoryAssignment3 = this.CreateInventoryAssignment(workOrder, part3, 13);

            //// Work Effort Time Entries
            var yesterday      = DateTimeFactory.CreateDateTime(this.Session.Now().AddDays(-1));
            var laterYesterday = DateTimeFactory.CreateDateTime(yesterday.AddHours(3));

            var today      = DateTimeFactory.CreateDateTime(this.Session.Now());
            var laterToday = DateTimeFactory.CreateDateTime(today.AddHours(4));

            var tomorrow      = DateTimeFactory.CreateDateTime(this.Session.Now().AddDays(1));
            var laterTomorrow = DateTimeFactory.CreateDateTime(tomorrow.AddHours(6));

            var timeEntryYesterday = this.CreateTimeEntry(yesterday, laterYesterday, frequencies.Day, workOrder);
            var timeEntryToday     = this.CreateTimeEntry(today, laterToday, frequencies.Hour, workOrder);
            var timeEntryTomorrow  = this.CreateTimeEntry(tomorrow, laterTomorrow, frequencies.Minute, workOrder);

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntryYesterday);
            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntryToday);
            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntryTomorrow);

            this.Session.Derive(true);

            // Act
            workOrder.Print();

            this.Session.Derive();
            this.Session.Commit();

            // Assert
            Assert.True(workOrder.PrintDocument.ExistMedia);

            var desktopDir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            var outputFile = System.IO.File.Create(System.IO.Path.Combine(desktopDir, "workTask.odt"));
            var stream     = new System.IO.MemoryStream(workOrder.PrintDocument.Media.MediaContent.Data);

            stream.CopyTo(outputFile);
            stream.Close();
        }
示例#10
0
        public void GivenParentWorkEffortAndTimeEntriesWithBillingRate_WhenInvoiced_ThenTimeEntryBillingRateIsUsed()
        {
            var frequencies = new TimeFrequencies(this.Session);

            var organisation = new Organisations(this.Session).Extent().First(o => o.IsInternalOrganisation);
            var customer     = new PersonBuilder(this.Session).WithLastName("Customer").Build();

            new CustomerRelationshipBuilder(this.Session).WithCustomer(customer).WithInternalOrganisation(organisation).Build();
            var employee = new PersonBuilder(this.Session).WithFirstName("Good").WithLastName("Worker").Build();

            new EmploymentBuilder(this.Session).WithEmployee(employee).WithEmployer(organisation).Build();

            var parentWorkOrder = new WorkTaskBuilder(this.Session).WithName("Parent Task").WithCustomer(customer).Build();

            this.Session.Derive(true);

            var yesterday      = DateTimeFactory.CreateDateTime(this.Session.Now().AddDays(-1));
            var laterYesterday = DateTimeFactory.CreateDateTime(yesterday.AddHours(3));

            var today      = DateTimeFactory.CreateDateTime(this.Session.Now());
            var laterToday = DateTimeFactory.CreateDateTime(today.AddHours(4));

            var tomorrow      = DateTimeFactory.CreateDateTime(this.Session.Now().AddDays(1));
            var laterTomorrow = DateTimeFactory.CreateDateTime(tomorrow.AddHours(6));

            var timeEntryYesterday = new TimeEntryBuilder(this.Session)
                                     .WithRateType(new RateTypes(this.Session).StandardRate)
                                     .WithFromDate(yesterday)
                                     .WithThroughDate(laterYesterday)
                                     .WithWorkEffort(parentWorkOrder)
                                     .WithAssignedBillingRate(10)
                                     .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntryYesterday);

            var timeEntryToday = new TimeEntryBuilder(this.Session)
                                 .WithRateType(new RateTypes(this.Session).StandardRate)
                                 .WithFromDate(today)
                                 .WithThroughDate(laterToday)
                                 .WithWorkEffort(parentWorkOrder)
                                 .WithAssignedBillingRate(12)
                                 .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntryToday);

            var childWorkOrder = new WorkTaskBuilder(this.Session).WithName("Child Task").WithCustomer(customer).Build();

            parentWorkOrder.AddChild(childWorkOrder);

            var timeEntryTomorrow = new TimeEntryBuilder(this.Session)
                                    .WithRateType(new RateTypes(this.Session).StandardRate)
                                    .WithFromDate(tomorrow)
                                    .WithThroughDate(laterTomorrow)
                                    .WithWorkEffort(childWorkOrder)
                                    .WithAssignedBillingRate(14)
                                    .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntryTomorrow);

            parentWorkOrder.Complete();

            this.Session.Derive(true);

            parentWorkOrder.Invoice();

            var salesInvoice = customer.SalesInvoicesWhereBillToCustomer.First;

            Assert.Equal(3, salesInvoice.InvoiceItems.Length);
            Assert.Equal(10, timeEntryYesterday.TimeEntryBillingsWhereTimeEntry.First.InvoiceItem.AssignedUnitPrice);
            Assert.Equal(3, timeEntryYesterday.TimeEntryBillingsWhereTimeEntry.First.InvoiceItem.Quantity);
            Assert.Equal(12, timeEntryToday.TimeEntryBillingsWhereTimeEntry.First.InvoiceItem.AssignedUnitPrice);
            Assert.Equal(4, timeEntryToday.TimeEntryBillingsWhereTimeEntry.First.InvoiceItem.Quantity);
            Assert.Equal(14, timeEntryTomorrow.TimeEntryBillingsWhereTimeEntry.First.InvoiceItem.AssignedUnitPrice);
            Assert.Equal(6, timeEntryTomorrow.TimeEntryBillingsWhereTimeEntry.First.InvoiceItem.Quantity);
        }
示例#11
0
        public void GivenWorkEffortAndTimeEntries_WhenDeriving_ThenActualStartAndCompletionDerived()
        {
            // Arrange
            var frequencies = new TimeFrequencies(this.Session);

            var customer             = new OrganisationBuilder(this.Session).WithName("Org1").Build();
            var internalOrganisation = new Organisations(this.Session).Extent().First(o => o.IsInternalOrganisation);

            new CustomerRelationshipBuilder(this.Session).WithCustomer(customer).WithInternalOrganisation(internalOrganisation).Build();

            var workOrder = new WorkTaskBuilder(this.Session).WithName("Task").WithCustomer(customer).WithTakenBy(internalOrganisation).Build();

            var employee = new PersonBuilder(this.Session).WithFirstName("Good").WithLastName("Worker").Build();

            new EmploymentBuilder(this.Session).WithEmployee(employee).WithEmployer(internalOrganisation).Build();

            this.Session.Derive(true);

            var yesterday      = DateTimeFactory.CreateDateTime(this.Session.Now().AddDays(-1));
            var laterYesterday = DateTimeFactory.CreateDateTime(yesterday.AddHours(3));

            var today      = DateTimeFactory.CreateDateTime(this.Session.Now());
            var laterToday = DateTimeFactory.CreateDateTime(today.AddHours(4));

            var tomorrow      = DateTimeFactory.CreateDateTime(this.Session.Now().AddDays(1));
            var laterTomorrow = DateTimeFactory.CreateDateTime(tomorrow.AddHours(6));

            var timeEntryToday = new TimeEntryBuilder(this.Session)
                                 .WithRateType(new RateTypes(this.Session).StandardRate)
                                 .WithFromDate(today)
                                 .WithThroughDate(laterToday)
                                 .WithWorkEffort(workOrder)
                                 .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntryToday);

            // Act
            this.Session.Derive(true);

            // Assert
            Assert.Equal(today, workOrder.ActualStart);
            Assert.Equal(laterToday, workOrder.ActualCompletion);

            //// Re-arrange
            var timeEntryYesterday = new TimeEntryBuilder(this.Session)
                                     .WithRateType(new RateTypes(this.Session).StandardRate)
                                     .WithFromDate(yesterday)
                                     .WithThroughDate(laterYesterday)
                                     .WithWorkEffort(workOrder)
                                     .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntryYesterday);

            // Act
            this.Session.Derive(true);

            // Assert
            Assert.Equal(yesterday, workOrder.ActualStart);
            Assert.Equal(laterToday, workOrder.ActualCompletion);

            //// Re-arrange

            var timeEntryTomorrow = new TimeEntryBuilder(this.Session)
                                    .WithRateType(new RateTypes(this.Session).StandardRate)
                                    .WithFromDate(tomorrow)
                                    .WithThroughDate(laterTomorrow)
                                    .WithTimeFrequency(frequencies.Minute)
                                    .WithWorkEffort(workOrder)
                                    .Build();

            employee.TimeSheetWhereWorker.AddTimeEntry(timeEntryTomorrow);

            // Act
            this.Session.Derive(true);

            // Assert
            Assert.Equal(yesterday, workOrder.ActualStart);
            Assert.Equal(laterTomorrow, workOrder.ActualCompletion);
        }
示例#12
0
        private static void CreateInvoiceItems(this WorkEffort @this, SalesInvoice salesInvoice)
        {
            var session           = @this.Strategy.Session;
            var timeBillingAmount = 0M;
            var hours             = 0M;
            var billableEntries   = new List <TimeEntry>();
            var frequencies       = new TimeFrequencies(session);

            foreach (TimeEntry timeEntry in @this.ServiceEntriesWhereWorkEffort)
            {
                if (timeEntry.IsBillable)
                {
                    billableEntries.Add(timeEntry);
                    var entryTimeSpan = (decimal)(timeEntry.ThroughDate - timeEntry.FromDate).Value.TotalMinutes;

                    if (timeEntry.ExistBillingRate)
                    {
                        var timeInTimeEntryRateFrequency = frequencies.Minute.ConvertToFrequency(entryTimeSpan, timeEntry.BillingFrequency);
                        timeBillingAmount += Math.Round((decimal)(timeEntry.BillingRate * timeInTimeEntryRateFrequency), 2);
                    }
                    else
                    {
                        var workEffortAssignmentRate      = @this.WorkEffortAssignmentRatesWhereWorkEffort.First;
                        var timeInWorkEffortRateFrequency = frequencies.Minute.ConvertToFrequency(entryTimeSpan, workEffortAssignmentRate.Frequency);
                        timeBillingAmount += Math.Round((decimal)(workEffortAssignmentRate.Rate * timeInWorkEffortRateFrequency), 2);
                    }
                }
            }

            if (timeBillingAmount > 0)
            {
                var invoiceItem = new SalesInvoiceItemBuilder(session)
                                  .WithInvoiceItemType(new InvoiceItemTypes(session).Time)
                                  .WithActualUnitPrice(timeBillingAmount)
                                  .WithQuantity(hours)
                                  .Build();

                salesInvoice.AddSalesInvoiceItem(invoiceItem);

                foreach (TimeEntry billableEntry in billableEntries)
                {
                    new TimeEntryBillingBuilder(session)
                    .WithTimeEntry(billableEntry)
                    .WithInvoiceItem(invoiceItem)
                    .Build();
                }
            }

            foreach (WorkEffortInventoryAssignment workEffortInventoryAssignment in @this.WorkEffortInventoryAssignmentsWhereAssignment)
            {
                var part            = workEffortInventoryAssignment.InventoryItem.Part;
                var priceComponents = GetPriceComponents(@this, part);

                var basePrice = 0M;
                foreach (var priceComponent in priceComponents)
                {
                    if (priceComponent.Strategy.Class.Equals(M.BasePrice.ObjectType))
                    {
                        if (priceComponent.ExistPrice)
                        {
                            if (basePrice < priceComponent.Price)
                            {
                                basePrice = (decimal)priceComponent.Price;
                            }
                        }
                    }
                }

                var invoiceItem = new SalesInvoiceItemBuilder(session)
                                  .WithInvoiceItemType(new InvoiceItemTypes(session).PartItem)
                                  .WithPart(part)
                                  .WithActualUnitPrice(basePrice)
                                  .WithQuantity(workEffortInventoryAssignment.Quantity)
                                  .Build();

                salesInvoice.AddSalesInvoiceItem(invoiceItem);

                new WorkEffortBillingBuilder(session)
                .WithWorkEffort(@this)
                .WithInvoiceItem(invoiceItem)
                .Build();
            }
        }
示例#13
0
        public void BaseOnDerive(ObjectOnDerive method)
        {
            var derivation = method.Derivation;

            derivation.Validation.AssertExists(this, this.Meta.TimeSheetWhereTimeEntry);
            derivation.Validation.AssertAtLeastOne(this, this.Meta.WorkEffort, this.Meta.EngagementItem);

            var useInternalRate = this.WorkEffort?.Customer is Organisation organisation && organisation.IsInternalOrganisation;
            var rateType        = useInternalRate ? new RateTypes(this.Session()).InternalRate : this.RateType;

            if (this.ExistTimeSheetWhereTimeEntry)
            {
                this.Worker = this.TimeSheetWhereTimeEntry.Worker;
            }

            //if (this.ExistWorker)
            //{
            //    var otherActiveTimeEntry = this.Worker.TimeEntriesWhereWorker.FirstOrDefault(v =>
            //                    v.Id != this.Id
            //                    && ((v.FromDate < this.FromDate && (!v.ExistThroughDate || v.ThroughDate > this.FromDate))
            //                        || (v.FromDate > this.FromDate && v.FromDate < this.ThroughDate)));

            //    if (otherActiveTimeEntry != null)
            //    {
            //        derivation.Validation.AddError(this, this.Meta.Worker, ErrorMessages.WorkerActiveTimeEntry.Replace("{0}", otherActiveTimeEntry.WorkEffort?.WorkEffortNumber));
            //    }
            //}

            var billingRate = 0M;

            if (this.AssignedBillingRate.HasValue)
            {
                billingRate = this.AssignedBillingRate.Value;
            }
            else
            {
                if (this.ExistWorkEffort)
                {
                    var workEffortAssignmentRate = this.WorkEffort.WorkEffortAssignmentRatesWhereWorkEffort.FirstOrDefault(v => v.RateType.Equals(this.RateType) && v.Frequency.Equals(this.BillingFrequency));
                    if (workEffortAssignmentRate != null)
                    {
                        billingRate = workEffortAssignmentRate.Rate;
                    }
                }

                if (billingRate == 0 &&
                    this.ExistWorkEffort &&
                    this.WorkEffort.ExistCustomer &&
                    (this.WorkEffort.Customer as Organisation)?.IsInternalOrganisation == false)
                {
                    var partyRate = this.WorkEffort.Customer.PartyRates.FirstOrDefault(v => v.RateType.Equals(rateType) &&
                                                                                       v.Frequency.Equals(this.BillingFrequency) &&
                                                                                       v.FromDate <= this.FromDate && (!v.ExistThroughDate || v.ThroughDate >= this.FromDate));
                    if (partyRate != null)
                    {
                        billingRate = partyRate.Rate;
                    }
                }

                if (billingRate == 0 && this.ExistWorker && this.ExistRateType)
                {
                    var partyRate = this.Worker.PartyRates.FirstOrDefault(v => v.RateType.Equals(rateType) &&
                                                                          v.Frequency.Equals(this.BillingFrequency) &&
                                                                          v.FromDate <= this.FromDate && (!v.ExistThroughDate || v.ThroughDate >= this.FromDate));
                    if (partyRate != null)
                    {
                        billingRate = partyRate.Rate;
                    }
                }

                if (billingRate == 0 && this.ExistWorkEffort && this.WorkEffort.ExistExecutedBy)
                {
                    var partyRate = this.WorkEffort.ExecutedBy.PartyRates.FirstOrDefault(v => v.RateType.Equals(rateType) &&
                                                                                         v.Frequency.Equals(this.BillingFrequency) &&
                                                                                         v.FromDate <= this.FromDate && (!v.ExistThroughDate || v.ThroughDate >= this.FromDate));
                    if (partyRate != null)
                    {
                        billingRate = partyRate.Rate;
                    }
                }
            }

            // rate before uplift
            var costRate = billingRate;

            if (useInternalRate && this.WorkEffort.Customer != this.WorkEffort.ExecutedBy)
            {
                billingRate = Rounder.RoundDecimal(billingRate * (1 + this.strategy.Session.GetSingleton().Settings.InternalLabourSurchargePercentage / 100), 2);
            }

            this.BillingRate = billingRate;

            if (this.ExistBillingRate)
            {
                derivation.Validation.AssertExists(this, this.Meta.BillingFrequency);
            }

            // calculate AmountOfTime Or ThroughDate
            var frequencies = new TimeFrequencies(this.Strategy.Session);

            this.AmountOfTime = null;

            if (this.ThroughDate != null)
            {
                var timeSpan = this.ThroughDate - this.FromDate;
                this.AmountOfTimeInMinutes = (decimal)timeSpan.Value.TotalMinutes;
                var amount = frequencies.Minute.ConvertToFrequency(this.AmountOfTimeInMinutes, this.TimeFrequency);

                if (amount == null)
                {
                    this.RemoveAmountOfTime();
                }
                else
                {
                    this.AmountOfTime = Rounder.RoundDecimal((decimal)amount, 2);
                }
            }
            else if (this.ExistAssignedAmountOfTime)
            {
                this.AmountOfTimeInMinutes = (decimal)this.TimeFrequency.ConvertToFrequency((decimal)this.AssignedAmountOfTime, frequencies.Minute);

                var timeSpan = TimeSpan.FromMinutes((double)this.AmountOfTimeInMinutes);
                this.ThroughDate = new DateTime(this.FromDate.Ticks, this.FromDate.Kind) + timeSpan;

                this.AmountOfTime = this.AssignedAmountOfTime;
            }
            else
            {
                var timeSpan = this.Session().Now() - this.FromDate;
                this.AmountOfTimeInMinutes = (decimal)timeSpan.TotalMinutes;
                var amount = frequencies.Minute.ConvertToFrequency(this.AmountOfTimeInMinutes, this.TimeFrequency);

                if (amount == null)
                {
                    this.RemoveAmountOfTime();
                }
                else
                {
                    this.AmountOfTime = Rounder.RoundDecimal((decimal)amount, 2);
                }
            }

            if (this.ExistBillingRate && this.ExistBillingFrequency)
            {
                if (this.BillableAmountOfTime.HasValue)
                {
                    this.BillableAmountOfTimeInMinutes = (decimal)this.TimeFrequency.ConvertToFrequency((decimal)this.BillableAmountOfTime, frequencies.Minute);
                }
                else
                {
                    this.BillableAmountOfTimeInMinutes = this.AmountOfTimeInMinutes;
                }

                var billableTimeInTimeEntryRateFrequency = Rounder.RoundDecimal((decimal)frequencies.Minute.ConvertToFrequency(this.BillableAmountOfTimeInMinutes, this.BillingFrequency), 2);

                this.BillingAmount = Rounder.RoundDecimal((decimal)(this.BillingRate * billableTimeInTimeEntryRateFrequency), 2);

                var timeSpendInTimeEntryRateFrequency = Rounder.RoundDecimal((decimal)frequencies.Minute.ConvertToFrequency(this.AmountOfTimeInMinutes, this.BillingFrequency), 2);
                this.Cost = Rounder.RoundDecimal((decimal)(costRate * timeSpendInTimeEntryRateFrequency), 2);
            }
        }