|
@@ -38,7 +38,7 @@ public class CustomerMYOBPoster : IMYOBPoster<Customer, CustomerMYOBPosterSettin
|
|
|
lastName = names.Length > 1 ? names[1] : "";
|
|
|
}
|
|
|
|
|
|
- private MYOBAddress ConvertAddress(Address address, int location, IContact contact)
|
|
|
+ private static MYOBAddress ConvertAddress(Address address, int location, IContact contact)
|
|
|
{
|
|
|
return new MYOBAddress
|
|
|
{
|
|
@@ -65,10 +65,117 @@ public class CustomerMYOBPoster : IMYOBPoster<Customer, CustomerMYOBPosterSettin
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- public IPostResult<Customer> Process(IDataModel<Customer> model)
|
|
|
+ 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/
|
|
|
|
|
|
+ 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);
|
|
|
+ myobCustomer.IsActive = customer.CustomerStatus.Active;
|
|
|
+ myobCustomer.Addresses =
|
|
|
+ [
|
|
|
+ ConvertAddress(customer.Delivery, 1, customer.DefaultContact),
|
|
|
+ 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<Exception>();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <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<Guid, Exception>(new Exception("Customer code is longer than 15 characters"));
|
|
|
+ }
|
|
|
+ var myobCustomer = new MYOBCustomer();
|
|
|
+ return UpdateCustomer(data, PosterUtils.LoadPosterSettings<Customer, CustomerMYOBPosterSettings>(), customer, myobCustomer, true)
|
|
|
+ .MapOk(() =>
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var result = service.UpdateEx(data.CompanyFile, myobCustomer, data.CompanyFileCredentials);
|
|
|
+ customer.PostedReference = result.UID.ToString();
|
|
|
+ return Result.Ok<Guid, Exception>(result.UID);
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ CoreUtils.LogException("", e, $"Error while posting customer {customer.ID}");
|
|
|
+ return Result.Error<Guid, Exception>(e);
|
|
|
+ }
|
|
|
+ }).Flatten();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ customer.PostedReference = customers.Items[0].UID.ToString();
|
|
|
+ return Result.Ok<Guid, Exception>(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);
|
|
@@ -77,108 +184,48 @@ public class CustomerMYOBPoster : IMYOBPoster<Customer, CustomerMYOBPosterSettin
|
|
|
|
|
|
foreach(var customer in customers)
|
|
|
{
|
|
|
- try
|
|
|
+ if(customer.Code.Length > 15)
|
|
|
{
|
|
|
- bool isNew;
|
|
|
- MYOBCustomer myobCustomer;
|
|
|
- if(Guid.TryParse(customer.PostedReference, out var myobID))
|
|
|
- {
|
|
|
- if(!service.Get(ConnectionData, myobID).Get(out var newCustomer, out var 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;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- myobCustomer = newCustomer;
|
|
|
- isNew = false;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
+ 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))
|
|
|
{
|
|
|
- myobCustomer = new MYOBCustomer();
|
|
|
- isNew = true;
|
|
|
+ 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;
|
|
|
+ }
|
|
|
|
|
|
- SplitName(customer.DefaultContact.Name, out var firstName, out var lastName);
|
|
|
-
|
|
|
- myobCustomer = new MYOBCustomer
|
|
|
+ if(UpdateCustomer(ConnectionData, Settings, customer, myobCustomer, isNew).Get(out error))
|
|
|
+ {
|
|
|
+ try
|
|
|
{
|
|
|
- CompanyName = customer.Name.Truncate(50),
|
|
|
- FirstName = firstName.Truncate(30),
|
|
|
- LastName = lastName.Truncate(20),
|
|
|
- IsIndividual = false,
|
|
|
- DisplayID = customer.Code.Truncate(15),
|
|
|
- IsActive = customer.CustomerStatus.Active,
|
|
|
- Addresses =
|
|
|
- [
|
|
|
- ConvertAddress(customer.Delivery, 1, customer.DefaultContact),
|
|
|
- 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)
|
|
|
+ var result = service.Update(ConnectionData.CompanyFile, myobCustomer, ConnectionData.CompanyFileCredentials);
|
|
|
+ results.AddSuccess(customer);
|
|
|
+ }
|
|
|
+ catch(Exception e)
|
|
|
{
|
|
|
- if (Settings.DefaultTaxCode.IsNullOrWhiteSpace())
|
|
|
- {
|
|
|
- throw new PostFailedMessageException("Default tax code has not been set up.");
|
|
|
- }
|
|
|
- else if(ConnectionData.GetMYOBTaxCodeUID(Settings.DefaultTaxCode).Get(out var taxID, out var error))
|
|
|
- {
|
|
|
- if (taxID.HasValue)
|
|
|
- {
|
|
|
- myobCustomer.SellingDetails.TaxCode.UID = taxID.Value;
|
|
|
- myobCustomer.SellingDetails.FreightTaxCode.UID = taxID.Value;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- results.AddFailed(customer, $"Failed to find TaxCode in MYOB with code {Settings.DefaultTaxCode}");
|
|
|
- continue;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- CoreUtils.LogException("", error, $"Failed to find TaxCode in MYOB with code {Settings.DefaultTaxCode}");
|
|
|
- results.AddFailed(customer, $"Failed to find TaxCode in MYOB with code {Settings.DefaultTaxCode}: {error.Message}");
|
|
|
- continue;
|
|
|
- }
|
|
|
+ CoreUtils.LogException("", e, $"Error while posting customer {customer.ID}");
|
|
|
+ results.AddFailed(customer, e.Message);
|
|
|
}
|
|
|
-
|
|
|
- // myobCustomer.SellingDetails.UseCustomerTaxCode =
|
|
|
- // myobCustomer.SellingDetails.Terms =
|
|
|
- // myobCustomer.SellingDetails.Credit =
|
|
|
- // myobCustomer.SellingDetails.TaxIdNumber =
|
|
|
- // myobCustomer.SellingDetails.Memo =
|
|
|
- // myboCustomer.PaymentDetails.Method =
|
|
|
- // myboCustomer.PaymentDetails.CardNumber =
|
|
|
- // myboCustomer.PaymentDetails.NameOnCard =
|
|
|
- // myboCustomer.PaymentDetails.BSBNumber =
|
|
|
- // myboCustomer.PaymentDetails.BankAccountNumber =
|
|
|
- // myboCustomer.PaymentDetails.BankAccountName =
|
|
|
- // myboCustomer.PaymentDetails.Notes =
|
|
|
-
|
|
|
- var result = service.Update(ConnectionData.CompanyFile, myobCustomer, ConnectionData.CompanyFileCredentials);
|
|
|
- results.AddSuccess(customer);
|
|
|
}
|
|
|
- catch (Exception e)
|
|
|
+ else
|
|
|
{
|
|
|
- CoreUtils.LogException("", e, $"Error while posting customer {customer.ID}");
|
|
|
- results.AddFailed(customer, e.Message);
|
|
|
+ results.AddFailed(customer, error.Message);
|
|
|
}
|
|
|
}
|
|
|
|