Preface
This is merely to get an idea of how to go about thinking with projects. Many steps are skipped or ignored for the sake of simplicity (eg many minor things in ticket for whats being imported aren’t important for the general idea).
1. Take a look at the ticket
https://jira.hutility.com/projects/P658/issues/P658-1
2. Clone the repo
Find the git url from https://code.hutility.com:3000/Hutility/658 (can find it through mapper https://code.hutility.com:3000/mapper/repos/664 if needed) in this case it is https://code.hutility.com:3000/Hutility/658.git. Now clone the repo, the way I approach this is to have a network directory with all of my git repos so that I can access it from any VM. For naming I begin with the project number and some relevant name (658 CB Squared AR Import) this makes it easy to find it in the directory.
3. Create the project
Create a new project using the latest Hutility AccPac Template (in this case it is Hutility AccPac Template 2017 10 11). Set the location to be within your cloned repo in a Source folder. Initially it may look like there are errors, build the project so that NuGet packages are downloaded.
4. Plan out the project structure
You can jot down ideas or go straight to putting together some of the below components if it is straight forward enough. The idea is to separate concerns so that each piece has an obvious single function. The more convoluted a class is, the more difficult it is to test, update or even read. Horizontal bloat is much better than vertical bloat (make more short classes instead of less large classes).
4.1 Models
4.2 Services
4.3 User Interface
For every project there must be at least some user interface component, even if it is as simple as a button. For more complicated projects you may have to create more views, in cases like this you may want to create more view model classes if it makes sense in the hierarchy. This can be a complicated topic so I will leave complicated implementations for another post.
4.4 How they fit together
So now we have a service that can create InvoiceLines and a service that can import them into Sage but we need to combine the two for the program to be useful. Usually this will be the ViewModel (the primary one or new ones you create) that ties them together.
5. Implementation
5.1 InvoiceLine
This class is very simple it is just one property per column created from the query. We do add one thing which will come into use later however. Add the Mappable attribute to the class. (it is from HuLib)
5.2 EntityService
The first thing to note is that we will need sql information for the import so we can add this as constructor arguments (it doesn’t make sense to do anything in this service without a connection). Following that we w ill need the function to get the invoice data.
public EntityService(string server, string database, string user, string pass) public IEnumerable GetInvoiceData(DateTime dateFrom, DateTime dateTo)
Since a single connection would likely be used for the lifespan of the EntityService, the constructor just creates the connection using the parameters. To make it simpler another HuLib function is used:
_connection = SQLUtility.CreateConnection(_server, _user, _pass, _database);
5.3 Wiring up EntityService properties (Config and UI)
public string Server { get; set; } public string Database { get; set; } public string User { get; set; } public EncryptedString Password { get; set; }
5.4 Wiring up the button for EntityService
public void Import() { EntityService entityService = new EntityService(Config.Server, Config.Database, Config.User, Config.Password); IEnumerable invoiceLines = entityService.GetInvoiceData(DateFrom, DateTo); }
AsyncCommandFactory commandFactory = new AsyncCommandFactory(StateManager, "Loading....");
Uncomment this and use it to create the new asynchronous command:
AsyncCommandFactory commandFactory = new AsyncCommandFactory(StateManager, "Loading...."); ImportCommand = commandFactory.Create(Import);
Thats it for the view model! Now to wire it up to the MainWindow.xaml. Find within MainWindow.xaml the grid that has a comment indicating it is where to add view code. We want to add a date from and to as well as a button to perform the import:
5.5 Test the pulling of data
Great now everything should be wired up (except the Sage portion of course), lets give it a run. Run the application, edit the configuration with the correct sql information and hit import. Placing a breakpoint at the end of the Import function can help us see what came out of the function (hopefully the invoice detail rows). If an error occurs note that the program doesn’t crash – the async command handles these cases for us and politely shows a textbox regarding the issue.
5.6 Implementing Sage Import
5.7 Finishing touches