Kenric Nugteren 1 год назад
Родитель
Сommit
681f465987

+ 16 - 1
prs.classes/Entities/Customer/Customer.cs

@@ -53,7 +53,7 @@ namespace Comal.Classes
     }
 
     [UserTracking(typeof(Job))]
-    public class Customer : Entity, IPersistent, IRemotable, ISchedulable, ILicense<ProjectManagementLicense>, IExportable, IImportable, IMergeable
+    public class Customer : Entity, IPersistent, IRemotable, ISchedulable, ILicense<ProjectManagementLicense>, IExportable, IImportable, IMergeable, IPostable
     {
         [EditorSequence(1)]
         [UniqueCodeEditor(Visible = Visible.Default, Editable = Editable.Enabled)]
@@ -79,6 +79,9 @@ namespace Comal.Classes
         [EditorSequence(6)]
         [TextBoxEditor]
         public string Email { get; set; }
+        
+        [EditorSequence(7)]
+        public CustomerStatusLink CustomerStatus { get; set; }
 
         [EditorSequence("Accounts", 1)]
         [Caption("Bill To")]
@@ -113,6 +116,18 @@ namespace Comal.Classes
         [Aggregate(typeof(ActiveSchedules))]
         public int ActiveSchedules { get; set; }
 
+        [NullEditor]
+        public DateTime Posted { get; set; }
+
+        [NullEditor]
+        public PostedStatus PostedStatus { get; set; }
+
+        [NullEditor]
+        public string PostedNote { get; set; }
+
+        [NullEditor]
+        public string PostedReference { get; set; }
+
         public override string ToString()
         {
             return Name;

+ 25 - 0
prs.classes/Entities/Customer/CustomerStatus/CustomerStatus.cs

@@ -0,0 +1,25 @@
+using InABox.Core;
+
+namespace Comal.Classes
+{
+    [UserTracking(typeof(Job))]
+    public class JobStatus : Entity, IRemotable, IPersistent, IJobStatus, ILicense<ProjectManagementLicense>, IExportable, IImportable, IMergeable
+    {
+        [UniqueCodeEditor(Visible = Visible.Default, Editable = Editable.Enabled)]
+        [EditorSequence(1)]
+        public string Code { get; set; }
+
+        [TextBoxEditor(Visible = Visible.Default)]
+        [EditorSequence(2)]
+        public string Description { get; set; }
+
+        [CheckBoxEditor(Visible = Visible.Optional)]
+        [EditorSequence(3)]
+        public bool Active { get; set; }
+
+        [CheckBoxEditor(Visible = Visible.Optional)]
+        [EditorSequence(4)]
+        public bool Default { get; set; }
+
+    }
+}

+ 20 - 0
prs.classes/Entities/Customer/CustomerStatus/CustomerStatusLink.cs

@@ -0,0 +1,20 @@
+using System;
+using InABox.Core;
+
+namespace Comal.Classes
+{
+    public class JobStatusLink : EntityLink<JobStatus>, IJobStatus
+    {
+        [LookupEditor(typeof(JobStatus))]
+        public override Guid ID { get; set; }
+
+        [CodeEditor(Visible = Visible.Default)]
+        public string Code { get; set; }
+
+        [TextBoxEditor(Visible = Visible.Optional, Editable = Editable.Hidden)]
+        public string Description { get; set; }
+
+        [CheckBoxEditor(Visible = Visible.Optional, Editable = Editable.Hidden)]
+        public bool Active { get; set; }
+    }
+}

+ 22 - 0
prs.classes/Entities/Customer/CustomerStatus/CustomerStatusLookups.cs

@@ -0,0 +1,22 @@
+using InABox.Core;
+
+namespace Comal.Classes
+{
+    public class CustomerStatusLookups : EntityLookup<CustomerStatus>
+    {
+        public override Columns<CustomerStatus> DefineColumns()
+        {
+            return new Columns<CustomerStatus>(ColumnTypeFlags.DefaultVisible);
+        }
+
+        public override Filter<CustomerStatus> DefineFilter()
+        {
+            return null;
+        }
+
+        public override SortOrder<CustomerStatus> DefineSortOrder()
+        {
+            return new SortOrder<CustomerStatus>(x => x.Description);
+        }
+    }
+}

+ 11 - 0
prs.classes/Entities/Customer/CustomerStatus/ICustomerStatus.cs

@@ -0,0 +1,11 @@
+namespace Comal.Classes
+{
+    public interface ICustomerStatus
+    {
+        string Code { get; set; }
+
+        string Description { get; set; }
+
+        bool Active { get; set; }
+    }
+}

+ 5 - 0
prs.desktop/Panels/Customers/CustomerPanel.xaml.cs

@@ -78,6 +78,11 @@ namespace PRSDesktop
             host.CreateSetupSeparator();
             AccountsSetupActions.CustomerSpreadsheetTemplates(host);
             //host.CreateToolbarButton(new PanelAction() { Caption = "Select Columns", OnExecute = DoSelectColumns, Image = PRSDesktop.Resources.shared });
+            PostUtils.CreateToolbarButtons(
+                host,
+                () => (DataModel(Selection.Selected) as IDataModel<Customer>)!,
+                () => Customers.Refresh(false, true),
+                true);
         }
 
         public void Refresh()

+ 127 - 0
prs.shared/Posters/MYOB/CustomerMYOBPoster.cs

@@ -0,0 +1,127 @@
+using Comal.Classes;
+using FastReport.Data;
+using InABox.Core;
+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;
+
+namespace PRS.Shared.Posters.MYOB;
+
+public class CustomerMYOBPoster : IMYOBPoster<Customer>
+{
+    public MYOBPosterSettings Settings { get; set; }
+    public MYOBGlobalPosterSettings GlobalSettings { get; set; }
+
+    public MYOBConnectionData ConnectionData { get; set; }
+
+    private 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] : "";
+    }
+    private static string TruncateString(string value, int maxLength)
+    {
+        if(value.Length > maxLength)
+        {
+            return value[..maxLength];
+        }
+        else
+        {
+            return value;
+        }
+    }
+
+    private MYOBAddress ConvertAddress(Address address, int location, IContact contact)
+    {
+        return new MYOBAddress
+        {
+            Location = location,
+            Street = address.Street,
+            City = address.City,
+            State = address.State,
+            PostCode = address.PostCode,
+            Phone1 = contact.Mobile,
+            Phone2 = contact.Telephone,
+            Email = contact.Email,
+            ContactName = contact.Name
+        };
+    }
+
+    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)
+        {
+            try
+            {
+                Guid.TryParse(customer.PostedReference, out var myobID);
+                SplitName(customer.DefaultContact.Name, out var firstName, out var lastName);
+
+                var myobCustomer = new MYOBCustomer
+                {
+                    UID = myobID,
+                    CompanyName = customer.Name,
+                    FirstName = firstName,
+                    LastName = lastName,
+                    IsIndividual = false,
+                    DisplayID = TruncateString(customer.Code, 15),
+                    IsActive = customer.CustomerStatus.Active,
+                    Addresses =
+                    [
+                        ConvertAddress(customer.Delivery, 1, customer.DefaultContact),
+                        ConvertAddress(customer.Postal, 2, customer.DefaultContact)
+                    ],
+                    // Notes = 
+                    CurrentBalance = (decimal)customer.Balance,
+                    // PaymentDetails = 
+                    // PhotoURI =
+                    // RowVersion = 
+                };
+                // myobCustomer.SellingDetails.SaleLayout = 
+                // myobCustomer.SellingDetails.PrintedFOrm = 
+                // myobCustomer.SellingDetails.InvoiceDelivery = 
+                // myobCustomer.SellingDetails.ItemPriceLevel = 
+                // 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;
+                // myobCustomer.SellingDetails.TaxCode = 
+                // myobCustomer.SellingDetails.FreightTaxCode = 
+                // myobCustomer.SellingDetails.UseCustomerTaxCode = 
+                // myobCustomer.SellingDetails.Terms = 
+                // myobCustomer.SellingDetails.Credit = 
+                // myobCustomer.SellingDetails.TaxIdNumber = 
+                // myobCustomer.SellingDetails.Memo = 
+
+                var result = service.Update(ConnectionData.CompanyFile, myobCustomer, ConnectionData.CompanyFileCredentials);
+                results.AddSuccess(customer);
+            }
+            catch (Exception e)
+            {
+                CoreUtils.LogException("", e, $"Error while posting customer {customer.ID}");
+                results.AddFailed(customer, e.Message);
+            }
+        }
+
+        return results;
+    }
+}

+ 0 - 23
prs.shared/Posters/MYOB/InvoiceMYOBPoster.cs

@@ -1,23 +0,0 @@
-using Comal.Classes;
-using InABox.Core;
-using InABox.Poster.MYOB;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace PRS.Shared.Posters.MYOB;
-
-public class InvoiceMYOBPoster : IMYOBPoster<Invoice>
-{
-    public MYOBPosterSettings Settings { get; set; }
-    public MYOBGlobalPosterSettings GlobalSettings { get; set; }
-
-    public MYOBConnectionData ConnectionData { get; set; }
-
-    public IPostResult<Invoice> Process(IDataModel<Invoice> model)
-    {
-        return new PostResult<Invoice>();
-    }
-}