context: // --------------------------------------------------------------------------------------------------------------------
  // <copyright file="WorkTask.cs" company="Allors bvba">
  //   Copyright 2002-2012 Allors bvba.
  // Dual Licensed under
  //   a) the General Public Licence v3 (GPL)
  //   b) the Allors License
  // The GPL License is included in the file gpl.txt.
  // The Allors License is an addendum to your contract.
  // Allors Applications is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  // GNU General Public License for more details.
  // For more information visit http://www.allors.com/legal
  // </copyright>
  // --------------------------------------------------------------------------------------------------------------------
  namespace Allors.Domain
  {
      using System;
      using System.Linq;
      using System.Collections.Generic;
      
      using Allors.Meta;
      using Allors.Services;
      using Sandwych.Reporting;
      using Microsoft.Extensions.DependencyInjection;
  
      public partial class WorkTask
      {
          public new string ToString() => this.WorkEffortNumber ?? this.Name;
  
          public static readonly TransitionalConfiguration[] StaticTransitionalConfigurations =
              {
                  new TransitionalConfiguration(M.WorkTask, M.WorkTask.WorkEffortState),
              };
  
          public TransitionalConfiguration[] TransitionalConfigurations => StaticTransitionalConfigurations;
  
          public void AppsOnBuild(ObjectOnBuild method)
          {
              var internalOrganisations = new Organisations(this.strategy.Session).Extent()
                  .Where(v => Equals(v.IsInternalOrganisation, true)).ToArray();
  
              if (!this.ExistTakenBy && internalOrganisations.Count() == 1)
              {
                  this.TakenBy = internalOrganisations.First();
              }
          }
  
          public void AppsOnDerive(ObjectOnDerive method)
          {
              if (!this.ExistWorkEffortNumber && this.ExistTakenBy)
              {
                  this.WorkEffortNumber = this.TakenBy.NextWorkEffortNumber();
              }
  
              this.RenderPrintDocument(this.TakenBy?.WorkTaskTemplate, new WorkTaskSandwychPrintModel(this).Model);
          }
  
          //public void AppsDelete(DeletableDelete method)
          //{
          //    foreach (WorkEffortStatus workEffortStatus in this.WorkEffortStatuses)
          //    {
          //        workEffortStatus.Delete();
          //    }
  
          //    foreach (WorkEffortAssignment workEffortAssignment in this.WorkEffortAssignmentsWhereAssignment)
          //    {
          //        workEffortAssignment.Delete();
          //    }
          //}
      }
  
      class WorkTaskSandwychPrintModel
      {
          private class WorkTaskPrintModel
          {
              public string Number;
              public ImageBlob Barcode;
              public string Purpose;
              public string Date;
              public string PurchaseOrder;
              public string ContactName;
              public string ContactTelephone;
              public string PaymentTerms;
              public string Facility;
              public string SalesRep;
  
              public WorkTaskPrintModel(WorkTask workTask)
              {
                  this.Number = workTask.WorkEffortNumber;
  
                  if (workTask.ExistWorkEffortNumber)
                  {
                      var session = workTask.Strategy.Session;
                      var barcodeService = session.ServiceProvider.GetRequiredService<IBarcodeService>();
                      var barcode = barcodeService.Generate(this.Number, BarcodeType.CODE_128, 320, 80);
                      this.Barcode = new ImageBlob("png", barcode);
                  }
  
                  this.Date = (workTask.ThroughDate() ?? DateTime.UtcNow).ToString("yyyy-MM-dd");
                  this.Purpose = String.Empty;
  
                  foreach (WorkEffortPurpose purpose in workTask.WorkEffortPurposes)
                  {
                      this.Purpose = this.Purpose.Equals(string.Empty) ? purpose.Name : $", {purpose.Name}";
                  }
  
                  // Details from associated Sales Order
                  if (workTask.ExistOrderItemFulfillment)
                  {
                      if (workTask.OrderItemFulfillment is SalesOrderItem salesOrderItem)
                      {
                          this.SalesRep = salesOrderItem.SalesRep.PartyName;
  
                          if (salesOrderItem.ExistSalesTerms)
                          {
                              var salesTerms = salesOrderItem.SalesTerms;
                              this.PaymentTerms = salesTerms.First.Description;
  
                              if (salesTerms.Count > 1)
                              {
                                  this.PaymentTerms += $" (+ {salesTerms.Count - 1})";
                              }
                          }
                          
                          var salesOrder = salesOrderItem.SalesOrderWhereSalesOrderItem;
                          this.PurchaseOrder = salesOrder?.OrderNumber;
  
                          if ((this.PaymentTerms == null) && salesOrder.ExistSalesTerms)
                          {
                              var salesTerms = salesOrder.SalesTerms;
                              this.PaymentTerms = salesTerms.First.Description;
  
                              if (salesTerms.Count > 1)
                              {
                                  this.PaymentTerms += $" (+ {salesTerms.Count - 1})";
                              }
                          }
                      }
  
                      if (workTask.ExistContactPerson)
                      {
                          var contact = workTask.ContactPerson;
                          this.ContactName = contact.PartyName;
                          this.ContactTelephone = contact.CellPhoneNumber?.Description ?? contact.GeneralPhoneNumber?.Description;
                      }
  
                      if ((this.PaymentTerms == null) && workTask.ExistCustomer && (workTask.Customer.PaymentNetDays() != null))
                      {
                          this.PaymentTerms = workTask.Customer.PaymentNetDays().ToString();
                      }
  
                      this.Facility = workTask.Facility?.Name;
                  }
              }
          }
  
          private class CustomerPrintModel
          {
              public string Number;
              public string Name;
              public string BillingAddress1;
              public string BillingAddress2;
              public string BillingAddress3;
              public string BillingCity;
              public string BillingState;
              public string BillingPostalCode;
              public string ShippingAddress1;
              public string ShippingAddress2;
              public string ShippingAddress3;
              public string ShippingCity;
              public string ShippingState;
              public string ShippingPostalCode;
  
              public CustomerPrintModel(Party customer)
              {
                  this.Number = customer.Id.ToString();
                  this.Name = customer.PartyName;
  
                  if (customer.BillingAddress is PostalAddress billingAddress)
                  {
                      this.BillingAddress1 = billingAddress.Address1;
                      this.BillingAddress2 = billingAddress.Address2;
                      this.BillingAddress3 = billingAddress.Address3;
  
                      if (billingAddress.ExistCity)
                      {
                          this.BillingCity = billingAddress.City.Name;
                          this.BillingState = billingAddress.City.State?.Name;
                      }
  
                      this.BillingPostalCode = billingAddress.PostalCode?.Code;
                  }
  
                  if (customer.ShippingAddress is PostalAddress shippingAddress)
                  {
                      this.ShippingAddress1 = shippingAddress.Address1;
                      this.ShippingAddress2 = shippingAddress.Address2;
                      this.ShippingAddress3 = shippingAddress.Address3;
  
                      if (shippingAddress.ExistCity)
                      {
                          this.ShippingCity = shippingAddress.City.Name;
  
gt:                         this.ShippingState = shippingAddress.City.State?.Name;