| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 | 
							- using Comal.Classes;
 
- using FastReport.Data;
 
- using InABox.Core;
 
- using InABox.Core.Postable;
 
- using InABox.Poster.MYOB;
 
- using MYOB.AccountRight.SDK.Services;
 
- using MYOB.AccountRight.SDK.Services.Contact;
 
- using System;
 
- using System.Collections.Generic;
 
- using System.Linq;
 
- using System.Net;
 
- using System.Text;
 
- using System.Threading.Tasks;
 
- using Customer = Comal.Classes.Customer;
 
- using MYOBCustomer = MYOB.AccountRight.SDK.Contracts.Version2.Contact.Customer;
 
- using MYOBAddress = MYOB.AccountRight.SDK.Contracts.Version2.Contact.Address;
 
- using MYOB.AccountRight.SDK.Contracts.Version2.Sale;
 
- using InABox.Clients;
 
- namespace PRS.Shared.Posters.MYOB;
 
- public class CustomerMYOBPosterSettings : MYOBPosterSettings
 
- {
 
-     [TextBoxEditor(ToolTip = "The MYOB tax code which should be used when posting customers")]
 
-     public string DefaultTaxCode { get; set; }
 
- }
 
- public static class ContactMYOBUtils
 
- {
 
-     public static void SplitName(string name, out string firstName, out string lastName)
 
-     {
 
-         var names = name.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
 
-         firstName = names.Length > 0 ? names[0] : "";
 
-         lastName = names.Length > 1 ? names[1] : "";
 
-     }
 
-     public static MYOBAddress ConvertAddress(Address address, int location, IContact contact)
 
-     {
 
-         return new MYOBAddress
 
-         {
 
-             Location = location,
 
-             Street = address.Street.Truncate(255),
 
-             City = address.City.Truncate(255),
 
-             State = address.State.Truncate(255),
 
-             PostCode = address.PostCode.Truncate(11),
 
-             Phone1 = contact.Mobile.Truncate(21),
 
-             Phone2 = contact.Telephone.Truncate(21),
 
-             Email = contact.Email.Truncate(255),
 
-             ContactName = contact.Name.Truncate(25)
 
-         };
 
-     }
 
- }
 
- public class CustomerMYOBPoster : IMYOBPoster<Customer, CustomerMYOBPosterSettings>
 
- {
 
-     public CustomerMYOBPosterSettings Settings { get; set; }
 
-     public MYOBGlobalPosterSettings GlobalSettings { get; set; }
 
-     public MYOBConnectionData ConnectionData { get; set; }
 
-     public bool BeforePost(IDataModel<Customer> model)
 
-     {
 
-         foreach (var (_, table) in model.ModelTables)
 
-         {
 
-             table.IsDefault = false;
 
-         }
 
-         model.SetIsDefault<Customer>(true);
 
-         model.SetColumns<Customer>(RequiredColumns());
 
-         return true;
 
-     }
 
-     public static Columns<Customer> RequiredColumns()
 
-     {
 
-         return Columns.None<Customer>()
 
-             .Add(x => x.ID)
 
-             .Add(x => x.PostedReference)
 
-             .Add(x => x.DefaultContact.Name)
 
-             .Add(x => x.Name)
 
-             .Add(x => x.Code)
 
-             .Add(x => x.CustomerStatus.ID)
 
-             .Add(x => x.CustomerStatus.Active)
 
-             .Add(x => x.Delivery.Street)
 
-             .Add(x => x.Delivery.City)
 
-             .Add(x => x.Delivery.State)
 
-             .Add(x => x.Delivery.PostCode)
 
-             .Add(x => x.Postal.Street)
 
-             .Add(x => x.Postal.City)
 
-             .Add(x => x.Postal.State)
 
-             .Add(x => x.Postal.PostCode)
 
-             .Add(x => x.DefaultContact.Mobile)
 
-             .Add(x => x.DefaultContact.Telephone)
 
-             .Add(x => x.DefaultContact.Email)
 
-             .Add(x => x.DefaultContact.Name)
 
-             .Add(x => x.DefaultContact.Mobile)
 
-             .Add(x => x.ABN);
 
-     }
 
-     public static Result<Exception> UpdateCustomer(MYOBConnectionData data, CustomerMYOBPosterSettings settings, Customer customer, MYOBCustomer myobCustomer, bool isNew)
 
-     {
 
-         // Documentation: https://developer.myob.com/api/myob-business-api/v2/contact/customer/
 
-         // Since this might be called from some other poster, we need to ensure we have the right columns.
 
-         Client.EnsureColumns(customer, RequiredColumns());
 
-         ContactMYOBUtils.SplitName(customer.DefaultContact.Name, out var firstName, out var lastName);
 
-         myobCustomer.CompanyName = customer.Name.Truncate(50);
 
-         myobCustomer.FirstName = firstName.Truncate(30);
 
-         myobCustomer.LastName = lastName.Truncate(20);
 
-         myobCustomer.IsIndividual = false;
 
-         myobCustomer.DisplayID = customer.Code.Truncate(15);
 
-         // If there is not customer status, we will use default to Active = true.
 
-         myobCustomer.IsActive = customer.CustomerStatus.ID == Guid.Empty || customer.CustomerStatus.Active;
 
-         myobCustomer.Addresses =
 
-         [
 
-             ContactMYOBUtils.ConvertAddress(customer.Delivery, 1, customer.DefaultContact),
 
-             ContactMYOBUtils.ConvertAddress(customer.Postal, 2, customer.DefaultContact)
 
-         ];
 
-         // Notes = 
 
-         // PhotoURI =
 
-         // RowVersion = 
 
-         myobCustomer.SellingDetails.SaleLayout = InvoiceLayoutType.NoDefault;
 
-         // myobCustomer.SellingDetails.PrintedFOrm = 
 
-         myobCustomer.SellingDetails.InvoiceDelivery = DocumentAction.PrintAndEmail;
 
-         // myobCustomer.SellingDetails.IncomeAccount = 
 
-         // myobCustomer.SellingDetails.ReceiptMemo = 
 
-         // myobCustomer.SellingDetails.SalesPerson = 
 
-         // myobCustomer.SellingDetails.SaleComment = 
 
-         // myobCustomer.SellingDetails.ShippingMethod = 
 
-         // myobCustomer.SellingDetails.HourlyBillRate = 
 
-         // myobCustomer.SellingDetails.ABNBranch = 
 
-         myobCustomer.SellingDetails.ABN = customer.ABN.Truncate(14);
 
-         if (isNew)
 
-         {
 
-             if (settings.DefaultTaxCode.IsNullOrWhiteSpace())
 
-             {
 
-                 throw new PostFailedMessageException("Default tax code has not been set up.");
 
-             }
 
-             else if(data.GetMYOBTaxCodeUID(settings.DefaultTaxCode).Get(out var taxID, out var error))
 
-             {
 
-                 if (taxID == Guid.Empty)
 
-                 {
 
-                     return Result.Error(new Exception($"Failed to find TaxCode in MYOB with code {settings.DefaultTaxCode}"));
 
-                 }
 
-                 myobCustomer.SellingDetails.TaxCode.UID = taxID;
 
-                 myobCustomer.SellingDetails.FreightTaxCode.UID = taxID;
 
-             }
 
-             else
 
-             {
 
-                 CoreUtils.LogException("", error, $"Failed to find TaxCode in MYOB with code {settings.DefaultTaxCode}");
 
-                 return Result.Error(new Exception($"Failed to find TaxCode in MYOB with code {settings.DefaultTaxCode}: {error.Message}", error));
 
-             }
 
-         }
 
-         return Result.Ok();
 
-     }
 
-     /// <summary>
 
-     /// Try to find a customer in MYOB which matches <paramref name="customer"/>, and if this fails, create a new one.
 
-     /// </summary>
 
-     /// <remarks>
 
-     /// After this has finished, <paramref name="customer"/> will be updated with <see cref="Customer.PostedReference"/> set to the correct ID.
 
-     /// <br/>
 
-     /// <paramref name="customer"/> needs to have at least <see cref="Customer.Code"/> and <see cref="Customer.PostedReference"/> as loaded columns.
 
-     /// </remarks>
 
-     /// <param name="data"></param>
 
-     /// <param name="customer">The customer to map to.</param>
 
-     /// <returns>The UID of the MYOB customer.</returns>
 
-     public static Result<Guid, Exception> MapCustomer(MYOBConnectionData data, Customer customer)
 
-     {
 
-         if(Guid.TryParse(customer.PostedReference, out var myobID))
 
-         {
 
-             return new Result<Guid, Exception>(myobID);
 
-         }
 
-         var service = new CustomerService(data.Configuration, null, data.AuthKey);
 
-         var result = service.Query(data, new Filter<MYOBCustomer>(x => x.DisplayID).IsEqualTo(customer.Code), top: 1);
 
-         return result.MapOk(customers =>
 
-         {
 
-             if(customers.Count == 0)
 
-             {
 
-                 if(customer.Code.Length > 15)
 
-                 {
 
-                     return Result.Error(new Exception("Customer code is longer than 15 characters"));
 
-                 }
 
-                 var myobCustomer = new MYOBCustomer();
 
-                 return UpdateCustomer(data, PosterUtils.LoadPosterSettings<Customer, CustomerMYOBPosterSettings>(), customer, myobCustomer, true)
 
-                     .MapOk<Result<Guid, Exception>>(() =>
 
-                     {
 
-                         try
 
-                         {
 
-                             var result = service.UpdateEx(data.CompanyFile, myobCustomer, data.CompanyFileCredentials);
 
-                             customer.PostedReference = result.UID.ToString();
 
-                             return Result.Ok(result.UID);
 
-                         }
 
-                         catch (Exception e)
 
-                         {
 
-                             CoreUtils.LogException("", e, $"Error while posting customer {customer.ID}");
 
-                             return Result.Error(e);
 
-                         }
 
-                     }).Flatten();
 
-             }
 
-             else
 
-             {
 
-                 customer.PostedReference = customers.Items[0].UID.ToString();
 
-                 return Result.Ok(customers.Items[0].UID);
 
-             }
 
-         }).Flatten();
 
-     }
 
-     public IPostResult<Customer> Process(IDataModel<Customer> model)
 
-     {
 
-         var results = new PostResult<Customer>();
 
-         var service = new CustomerService(ConnectionData.Configuration, null, ConnectionData.AuthKey);
 
-         var customers = model.GetTable<Customer>().ToArray<Customer>();
 
-         
 
-         foreach(var customer in customers)
 
-         {
 
-             if(customer.Code.Length > 15)
 
-             {
 
-                 results.AddFailed(customer, "Code is longer than 15 characters.");
 
-                 continue;
 
-             }
 
-             bool isNew;
 
-             MYOBCustomer myobCustomer;
 
-             Exception? error;
 
-             if(Guid.TryParse(customer.PostedReference, out var myobID))
 
-             {
 
-                 if(!service.Get(ConnectionData, myobID).Get(out var newCustomer, out error))
 
-                 {
 
-                     CoreUtils.LogException("", error, $"Failed to find Customer in MYOB with id {myobID}");
 
-                     results.AddFailed(customer, $"Failed to find Customer in MYOB with id {myobID}: {error.Message}");
 
-                     continue;
 
-                 }
 
-                 myobCustomer = newCustomer;
 
-                 isNew = false;
 
-             }
 
-             else
 
-             {
 
-                 myobCustomer = new MYOBCustomer();
 
-                 isNew = true;
 
-             }
 
-             if(UpdateCustomer(ConnectionData, Settings, customer, myobCustomer, isNew).Get(out error))
 
-             {
 
-                 try
 
-                 {
 
-                     var result = service.UpdateEx(ConnectionData.CompanyFile, myobCustomer, ConnectionData.CompanyFileCredentials);
 
-                     customer.PostedReference = result.UID.ToString();
 
-                     results.AddSuccess(customer);
 
-                 }
 
-                 catch(Exception e)
 
-                 {
 
-                     CoreUtils.LogException("", e, $"Error while posting customer {customer.ID}");
 
-                     results.AddFailed(customer, e.Message);
 
-                 }
 
-             }
 
-             else
 
-             {
 
-                 results.AddFailed(customer, error.Message);
 
-             }
 
-         }
 
-         return results;
 
-     }
 
- }
 
- public class CustomerMYOBPosterEngine<T> : MYOBPosterEngine<Customer, CustomerMYOBPosterSettings> { }
 
 
  |