CustomerMYOBPoster.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. using Comal.Classes;
  2. using FastReport.Data;
  3. using InABox.Core;
  4. using InABox.Core.Postable;
  5. using InABox.Poster.MYOB;
  6. using MYOB.AccountRight.SDK.Services;
  7. using MYOB.AccountRight.SDK.Services.Contact;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Net;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. using Customer = Comal.Classes.Customer;
  15. using MYOBCustomer = MYOB.AccountRight.SDK.Contracts.Version2.Contact.Customer;
  16. using MYOBAddress = MYOB.AccountRight.SDK.Contracts.Version2.Contact.Address;
  17. using MYOB.AccountRight.SDK.Contracts.Version2.Sale;
  18. namespace PRS.Shared.Posters.MYOB;
  19. public class CustomerMYOBPosterSettings : MYOBPosterSettings
  20. {
  21. [TextBoxEditor(ToolTip = "The MYOB tax code which should be used when posting customers")]
  22. public string DefaultTaxCode { get; set; }
  23. }
  24. public class CustomerMYOBPoster : IMYOBPoster<Customer, CustomerMYOBPosterSettings>
  25. {
  26. public CustomerMYOBPosterSettings Settings { get; set; }
  27. public MYOBGlobalPosterSettings GlobalSettings { get; set; }
  28. public MYOBConnectionData ConnectionData { get; set; }
  29. private static void SplitName(string name, out string firstName, out string lastName)
  30. {
  31. var names = name.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
  32. firstName = names.Length > 0 ? names[0] : "";
  33. lastName = names.Length > 1 ? names[1] : "";
  34. }
  35. private MYOBAddress ConvertAddress(Address address, int location, IContact contact)
  36. {
  37. return new MYOBAddress
  38. {
  39. Location = location,
  40. Street = address.Street.Truncate(255),
  41. City = address.City.Truncate(255),
  42. State = address.State.Truncate(255),
  43. PostCode = address.PostCode.Truncate(11),
  44. Phone1 = contact.Mobile.Truncate(21),
  45. Phone2 = contact.Telephone.Truncate(21),
  46. Email = contact.Email.Truncate(255),
  47. ContactName = contact.Name.Truncate(25)
  48. };
  49. }
  50. public bool BeforePost(IDataModel<Customer> model)
  51. {
  52. foreach (var (_, table) in model.ModelTables)
  53. {
  54. table.IsDefault = false;
  55. }
  56. model.SetIsDefault<Customer>(true);
  57. return true;
  58. }
  59. public IPostResult<Customer> Process(IDataModel<Customer> model)
  60. {
  61. // Documentation: https://developer.myob.com/api/myob-business-api/v2/contact/customer/
  62. var results = new PostResult<Customer>();
  63. var service = new CustomerService(ConnectionData.Configuration, null, ConnectionData.AuthKey);
  64. var customers = model.GetTable<Customer>().ToArray<Customer>();
  65. foreach(var customer in customers)
  66. {
  67. try
  68. {
  69. bool isNew;
  70. MYOBCustomer myobCustomer;
  71. if(Guid.TryParse(customer.PostedReference, out var myobID))
  72. {
  73. if(!service.Get(ConnectionData, myobID).Get(out var newCustomer, out var error))
  74. {
  75. CoreUtils.LogException("", error, $"Failed to find Customer in MYOB with id {myobID}");
  76. results.AddFailed(customer, $"Failed to find Customer in MYOB with id {myobID}: {error.Message}");
  77. continue;
  78. }
  79. else
  80. {
  81. myobCustomer = newCustomer;
  82. isNew = false;
  83. }
  84. }
  85. else
  86. {
  87. myobCustomer = new MYOBCustomer();
  88. isNew = true;
  89. }
  90. SplitName(customer.DefaultContact.Name, out var firstName, out var lastName);
  91. myobCustomer = new MYOBCustomer
  92. {
  93. CompanyName = customer.Name.Truncate(50),
  94. FirstName = firstName.Truncate(30),
  95. LastName = lastName.Truncate(20),
  96. IsIndividual = false,
  97. DisplayID = customer.Code.Truncate(15),
  98. IsActive = customer.CustomerStatus.Active,
  99. Addresses =
  100. [
  101. ConvertAddress(customer.Delivery, 1, customer.DefaultContact),
  102. ConvertAddress(customer.Postal, 2, customer.DefaultContact)
  103. ],
  104. // Notes =
  105. // PhotoURI =
  106. // RowVersion =
  107. };
  108. myobCustomer.SellingDetails.SaleLayout = InvoiceLayoutType.NoDefault;
  109. // myobCustomer.SellingDetails.PrintedFOrm =
  110. myobCustomer.SellingDetails.InvoiceDelivery = DocumentAction.PrintAndEmail;
  111. // myobCustomer.SellingDetails.IncomeAccount =
  112. // myobCustomer.SellingDetails.ReceiptMemo =
  113. // myobCustomer.SellingDetails.SalesPerson =
  114. // myobCustomer.SellingDetails.SaleComment =
  115. // myobCustomer.SellingDetails.ShippingMethod =
  116. // myobCustomer.SellingDetails.HourlyBillRate =
  117. // myobCustomer.SellingDetails.ABNBranch =
  118. myobCustomer.SellingDetails.ABN = customer.ABN.Truncate(14);
  119. if (isNew)
  120. {
  121. if (Settings.DefaultTaxCode.IsNullOrWhiteSpace())
  122. {
  123. throw new PostFailedMessageException("Default tax code has not been set up.");
  124. }
  125. else if(ConnectionData.GetMYOBTaxCodeUID(Settings.DefaultTaxCode).Get(out var taxID, out var error))
  126. {
  127. if (taxID.HasValue)
  128. {
  129. myobCustomer.SellingDetails.TaxCode.UID = taxID.Value;
  130. myobCustomer.SellingDetails.FreightTaxCode.UID = taxID.Value;
  131. }
  132. else
  133. {
  134. results.AddFailed(customer, $"Failed to find TaxCode in MYOB with code {Settings.DefaultTaxCode}");
  135. continue;
  136. }
  137. }
  138. else
  139. {
  140. CoreUtils.LogException("", error, $"Failed to find TaxCode in MYOB with code {Settings.DefaultTaxCode}");
  141. results.AddFailed(customer, $"Failed to find TaxCode in MYOB with code {Settings.DefaultTaxCode}: {error.Message}");
  142. continue;
  143. }
  144. }
  145. // myobCustomer.SellingDetails.UseCustomerTaxCode =
  146. // myobCustomer.SellingDetails.Terms =
  147. // myobCustomer.SellingDetails.Credit =
  148. // myobCustomer.SellingDetails.TaxIdNumber =
  149. // myobCustomer.SellingDetails.Memo =
  150. // myboCustomer.PaymentDetails.Method =
  151. // myboCustomer.PaymentDetails.CardNumber =
  152. // myboCustomer.PaymentDetails.NameOnCard =
  153. // myboCustomer.PaymentDetails.BSBNumber =
  154. // myboCustomer.PaymentDetails.BankAccountNumber =
  155. // myboCustomer.PaymentDetails.BankAccountName =
  156. // myboCustomer.PaymentDetails.Notes =
  157. var result = service.Update(ConnectionData.CompanyFile, myobCustomer, ConnectionData.CompanyFileCredentials);
  158. results.AddSuccess(customer);
  159. }
  160. catch (Exception e)
  161. {
  162. CoreUtils.LogException("", e, $"Error while posting customer {customer.ID}");
  163. results.AddFailed(customer, e.Message);
  164. }
  165. }
  166. return results;
  167. }
  168. }
  169. public class CustomerMYOBPosterEngine : MYOBPosterEngine<Customer, CustomerMYOBPosterSettings> { }