public static async Task SyncTrucksTable(CancellationToken cToken, UnitOfWork uow) { var trucks = await DocumentDBContext.GetAllItemsAsync <TruckEntity>(p => p.EntityType == EntityType.TRUCK); var localTruckIds = uow.TruckRepository.GetAllIds(); if (cToken.IsCancellationRequested) { return; } using (var addWork = new UnitOfWork()) { addWork.DisableChangeTracking(); AddRemoteEntitiesToLocalOfType <TruckEntity>(addWork, addWork.TruckRepository, cToken, trucks, localTruckIds); } if (cToken.IsCancellationRequested) { return; } using (var updateWork = new UnitOfWork()) { updateWork.DisableChangeTracking(); SyncHelper.UpdateRemoteEntitiesOnLocalOfType <TruckEntity>(updateWork, updateWork.TruckRepository, cToken, trucks, localTruckIds, true); } if (cToken.IsCancellationRequested) { return; } SyncHelper.DeleteEntitiesOfTypeNoSourceCheck <TruckEntity>(uow, uow.TruckRepository, cToken, trucks); }
private async Task <bool> tryDownloadSettings() { bool savedSettings = false; try { using (var dp = SimpleIoc.Default.GetInstance <IUnitOfWorkFactory>().CreateUnitOfWork()) { var syncedSettings = await DocumentDBContext.GetAllItemsAsync <SyncedSettings>(p => p.EntityType == EntityType.SETTING_SUMMARY); var settingsToSave = syncedSettings.FirstOrDefault(); var localSyncedSetting = dp.SyncedSettingsRepo.GetAll().FirstOrDefault(); settingsToSave.SyncedToCloud = true; if (localSyncedSetting == null) { dp.SyncedSettingsRepo.Add(settingsToSave); } else { dp.SyncedSettingsRepo.Update(settingsToSave); } dp.SaveChanges(); savedSettings = true; } } catch (Exception exc) { Logging.Logger.Log(exc); } return(savedSettings); }
private static async Task ClearDownloadedListsData(string appDataPath) { try { Console.WriteLine("Releasing downloaded lists..."); string settingsFile = appDataPath + "\\Truck\\settings.txt"; string encryptedString = System.IO.File.ReadAllText(settingsFile); string decryptedString = CottonDBMS.Helpers.EncryptionHelper.Decrypt(encryptedString); var parms = Newtonsoft.Json.JsonConvert.DeserializeObject <TruckAppInstallParams>(decryptedString); if (!string.IsNullOrEmpty(parms.EndPoint) && !string.IsNullOrEmpty(parms.Key) && !string.IsNullOrEmpty(parms.TruckID)) { DocumentDBContext.Initialize(parms.EndPoint, parms.Key); Console.WriteLine("Looking for downloaded lists..."); var docs = await DocumentDBContext.GetAllItemsAsync <TruckListsDownloaded>(p => p.Id == "TRUCKDOWNLOADS_" + parms.TruckID); if (docs.Count() > 0) { Console.WriteLine("Releasing lists..."); //remove document tracking lists this truck has downloaded //this allows them to be released for delete etc at the gin await DocumentDBContext.DeleteItemAsync <TruckListsDownloaded>("TRUCKDOWNLOADS_" + parms.TruckID); } } else { Console.WriteLine("One or more settings null."); } } catch (Exception exc) { Console.WriteLine(exc.Message); Console.WriteLine(exc.StackTrace); Console.WriteLine("Press enter to continue."); Console.ReadLine(); } }
public static async Task SyncModuleOwnershipTable(UnitOfWork uow, DateTime lastSyncTime, CancellationToken token) { //Sync module ownership table //get only modules updated or created var remoteModuleOwnerships = await DocumentDBContext.GetAllItemsAsync <ModuleOwnershipEntity>(p => p.EntityType == EntityType.MODULE_OWNERSHIP && (p.Created > lastSyncTime || (p.Updated.HasValue && p.Updated > lastSyncTime))); if (token.IsCancellationRequested) { return; } var localModuleOwnershipIds = uow.ModuleOwnershipRepository.GetAllIds(); if (token.IsCancellationRequested) { return; } using (var addWork = new UnitOfWork()) { addWork.DisableChangeTracking(); AddRemoteEntitiesToLocalOfType <ModuleOwnershipEntity>(addWork, addWork.ModuleOwnershipRepository, token, remoteModuleOwnerships, localModuleOwnershipIds); } if (token.IsCancellationRequested) { return; } using (var updateWork = new UnitOfWork()) { updateWork.DisableChangeTracking(); UpdateRemoteEntitiesOnLocalOfType <ModuleOwnershipEntity>(updateWork, updateWork.ModuleOwnershipRepository, token, remoteModuleOwnerships, localModuleOwnershipIds, false); } }
private async Task <bool> tryDownloadTrucksFromCloud() { bool trucksDownloaded = false; using (var dp = SimpleIoc.Default.GetInstance <IUnitOfWorkFactory>().CreateUnitOfWork()) { try { Logging.Logger.Log("INFO", "Fetch local trucks."); var localTrucks = dp.TruckRepository.GetAll(); Logging.Logger.Log("INFO", "Fetch local Drivers."); var localDrivers = dp.DriverRepository.GetAll(); Logging.Logger.Log("INFO", "Fetch current truck."); var currentTruck = dp.SettingsRepository.GetCurrentTruck(); Logging.Logger.Log("INFO", "Fetch current driver."); var currentDriver = dp.SettingsRepository.GetCurrentDriver(); if (currentDriver == null || currentTruck == null) //if no truck or driver set try to pull down from cloud and set a truck/driver { Logging.Logger.Log("INFO", "Initialize document db context."); CottonDBMS.Cloud.DocumentDBContext.Initialize(endpoint, key); Logging.Logger.Log("INFO", "Download trucks from cloud."); var trucks = await DocumentDBContext.GetAllItemsAsync <TruckEntity>(p => p.EntityType == EntityType.TRUCK); Logging.Logger.Log("INFO", "Download drivers from cloud."); var drivers = await DocumentDBContext.GetAllItemsAsync <DriverEntity>(p => p.EntityType == EntityType.DRIVER); if (localTrucks.Count() == 0) { Logging.Logger.Log("INFO", "Adding local trucks."); Trucks.Add(new ComboBoxItemViewModel { DisplayText = "-- Choose Truck --", ID = "" }); foreach (var t in trucks) { Logging.Logger.Log("INFO", "Adding truck " + t.Name); dp.TruckRepository.Add(t); Trucks.Add(new ComboBoxItemViewModel { DisplayText = t.Name, ID = t.Id.ToString() }); } } if (localDrivers.Count() == 0) { Drivers.Add(new ComboBoxItemViewModel { DisplayText = "-- Choose Driver --", ID = "" }); foreach (var d in drivers) { Logging.Logger.Log("INFO", "Adding driver " + d.Name); Drivers.Add(new ComboBoxItemViewModel { DisplayText = d.Name, ID = d.Id.ToString() }); dp.DriverRepository.Add(d); } } Logging.Logger.Log("INFO", "Saving db changes"); dp.SaveChanges(); Logging.Logger.Log("INFO", "Db changes saved"); trucksDownloaded = true; } else { Logging.Logger.Log("INFO", "Driver and truck already set."); } } catch (Exception exc) { Logging.Logger.Log(exc); } return(trucksDownloaded); } }
private async Task <bool> ValidateForm() { bool isValid = true; clearErrors(); if (string.IsNullOrWhiteSpace(_documentDbConnection)) { isValid = false; HasDocumentDbConnectionErrorMessage = true; DocumentDbConnectionErrorMessage = "required"; } if (string.IsNullOrWhiteSpace(DocumentDbEndpoint)) { isValid = false; HasDocumentDbEndpointErrorMessage = true; DocumentDbEndpointErrorMessage = "required"; } else if (!ValidationHelper.ValidUrl(DocumentDbEndpoint)) { isValid = false; HasDocumentDbEndpointErrorMessage = true; DocumentDbEndpointErrorMessage = "Invalid URL"; } if (!HasDocumentDbConnectionErrorMessage && !HasDocumentDbEndpointErrorMessage) { try { DocumentDBContext.Initialize(_documentDbEndpoint, _documentDbConnection); var trucks = await DocumentDBContext.GetAllItemsAsync <TruckEntity>(p => p.EntityType == EntityType.TRUCK); } catch (Exception exc) { isValid = false; HasDocumentDbEndpointErrorMessage = true; DocumentDbEndpointErrorMessage = "Unable to connect."; Logging.Logger.Log(exc); } } if (string.IsNullOrWhiteSpace(TareWeight)) { isValid = false; HasTareWeightErrorMessage = true; TareWeightErrorMessage = "required"; } else if (!ValidationHelper.ValidDecimal(TareWeight)) { isValid = false; HasTareWeightErrorMessage = true; TareWeightErrorMessage = "Invalid decimal number."; } if (BarcodePortName != "NONE" && BarcodePortName == PortName) { isValid = false; HasBarcodePortErrorMessage = true; } return(isValid); }
private void ExecuteSave() { Task.Run(async() => { string key = ""; string endpoint = ""; bool shutDown = false; using (var dp = SimpleIoc.Default.GetInstance <IUnitOfWorkFactory>().CreateUnitOfWork()) { var documentDbSetting = dp.SettingsRepository.FindSingle(x => x.Key == TruckClientSettingKeys.DOCUMENT_DB_KEY); var endpointSetting = dp.SettingsRepository.FindSingle(x => x.Key == TruckClientSettingKeys.DOCUMENTDB_ENDPOINT); if (documentDbSetting != null) { key = documentDbSetting.Value; } if (endpointSetting != null) { endpoint = endpointSetting.Value; } if (string.IsNullOrWhiteSpace(key) || string.IsNullOrWhiteSpace(endpoint)) { shutDown = true; } } if (string.IsNullOrWhiteSpace(_documentDbConnection)) { ShowErrorMessage = true; ErrorMessage = "Document db key is required."; } else if (string.IsNullOrWhiteSpace(_documentDbEndpoint)) { ShowErrorMessage = true; ErrorMessage = "Document db endpoint is required."; } else { ErrorMessage = ""; ShowErrorMessage = false; Messenger.Default.Send <BusyMessage>(new Messages.BusyMessage { IsBusy = true, Message = "Saving..." }); using (var dp = SimpleIoc.Default.GetInstance <IUnitOfWorkFactory>().CreateUnitOfWork()) { var documentDbEndpointSetting = dp.SettingsRepository.FindSingle(x => x.Key == TruckClientSettingKeys.DOCUMENTDB_ENDPOINT); var documentDbKeySetting = dp.SettingsRepository.FindSingle(x => x.Key == TruckClientSettingKeys.DOCUMENT_DB_KEY); var syncIntervalSetting = dp.SettingsRepository.FindSingle(x => x.Key == TruckClientSettingKeys.DATA_SYNC_INTERVAL); var localTrucks = dp.TruckRepository.GetAll(); var localDrivers = dp.DriverRepository.GetAll(); if (documentDbKeySetting != null) { documentDbKeySetting.Value = _documentDbConnection; } else { documentDbKeySetting = new Setting(); documentDbKeySetting.Key = TruckClientSettingKeys.DOCUMENT_DB_KEY; documentDbKeySetting.Value = _documentDbConnection; dp.SettingsRepository.Add(documentDbKeySetting); } if (documentDbEndpointSetting != null) { documentDbEndpointSetting.Value = _documentDbEndpoint; } else { documentDbEndpointSetting = new Setting(); documentDbEndpointSetting.Key = TruckClientSettingKeys.DOCUMENTDB_ENDPOINT; documentDbEndpointSetting.Value = _documentDbEndpoint; dp.SettingsRepository.Add(documentDbEndpointSetting); } if (syncIntervalSetting != null) { syncIntervalSetting.Value = _dataSyncInterval.ToString(); } else { syncIntervalSetting = new Setting(); syncIntervalSetting.Key = TruckClientSettingKeys.DATA_SYNC_INTERVAL; syncIntervalSetting.Value = _dataSyncInterval.ToString(); dp.SettingsRepository.Add(syncIntervalSetting); } AggregateDataProvider.UpdateReadDelay(_dataSyncInterval); dp.SaveChanges(); try { var currentTruck = dp.SettingsRepository.GetCurrentTruck(); var currentDriver = dp.SettingsRepository.GetCurrentDriver(); if (currentDriver == null || currentTruck == null) //if no truck or driver set try to pull down from cloud and set a truck/driver { CottonDBMS.Cloud.DocumentDBContext.Initialize(_documentDbEndpoint, _documentDbConnection); var trucks = await DocumentDBContext.GetAllItemsAsync <TruckEntity>(p => p.EntityType == EntityType.TRUCK); var drivers = await DocumentDBContext.GetAllItemsAsync <DriverEntity>(p => p.EntityType == EntityType.DRIVER); if (localTrucks.Count() == 0) { foreach (var t in trucks) { dp.TruckRepository.Add(t); } } if (localDrivers.Count() == 0) { foreach (var d in drivers) { dp.DriverRepository.Add(d); } } dp.SaveChanges(); localTrucks = dp.TruckRepository.GetAll(); localDrivers = dp.DriverRepository.GetAll(); if (localTrucks.Count() > 0) { dp.SettingsRepository.UpsertSetting(TruckClientSettingKeys.TRUCK_ID, localTrucks.First().Id); } if (localDrivers.Count() > 0) { dp.SettingsRepository.UpsertSetting(TruckClientSettingKeys.DRIVER_ID, localDrivers.First().Id); } dp.SaveChanges(); } } catch (Exception exc) { ErrorMessage = "Unable to connect to cloud."; ShowErrorMessage = true; } try { var syncedSettings = await DocumentDBContext.GetAllItemsAsync <SyncedSettings>(p => p.EntityType == EntityType.SETTING_SUMMARY); var settingsToSave = syncedSettings.FirstOrDefault(); var localSyncedSetting = dp.SyncedSettingsRepo.GetAll().FirstOrDefault(); settingsToSave.SyncedToCloud = true; if (localSyncedSetting == null) { dp.SyncedSettingsRepo.Add(settingsToSave); dp.SaveChanges(); } } catch (Exception exc) { ErrorMessage = "Unable to retrieve system settings."; ShowErrorMessage = true; Logging.Logger.Log(exc); } } Messenger.Default.Send <BusyMessage>(new Messages.BusyMessage { IsBusy = true, Message = "Settings Saved." }); System.Threading.Thread.Sleep(2000); Messenger.Default.Send <BusyMessage>(new Messages.BusyMessage { IsBusy = false, Message = "" }); if (shutDown) { Environment.Exit(0); } } CottonDBMS.TruckApp.Helpers.SettingsHelper.PersistSettingsToAppData(); }); }
public static async Task DoSync() { try { if (!hasConnection()) { return; } using (var uow = new UnitOfWork()) { var documentDbSetting = uow.SettingsRepository.FindSingle(x => x.Key == TruckClientSettingKeys.DOCUMENT_DB_KEY); var endpointSetting = uow.SettingsRepository.FindSingle(x => x.Key == TruckClientSettingKeys.DOCUMENTDB_ENDPOINT); DocumentDBContext.Initialize(endpointSetting.Value, documentDbSetting.Value); //return; if (DocumentDBContext.Initialized) { try { var truck = uow.SettingsRepository.GetCurrentTruck(); List <PickupListEntity> pickupLists = new List <PickupListEntity>(); Logging.Logger.Log("INFO", "Fetching pickuplists."); if (truck != null) { //process deleted documents - this mainly cleans out the Docs to process table //except for PickupLists if the truck deleted a pickup list a Release request doc is put in the cloud //so the gin can remove the truck assignment List <TruckPickupListRelease> releaseDocs = new List <TruckPickupListRelease>(); //get all lists that have been released by this truck previously await processDeletedDocuments(uow, token, truck.Id, releaseDocs); var cloudReleaseDocs = await DocumentDBContext.GetAllItemsAsync <TruckPickupListRelease>(x => x.TruckID == truck.Id); releaseDocs.AddRange(cloudReleaseDocs); var tempLists = await DocumentDBContext.GetAllItemsAsync <PickupListEntity>(p => p.EntityType == EntityType.PICKUPLIST && p.Source == InputSource.GIN && p.AssignedTruckIDs.Contains(truck.Id), 100); foreach (var list in tempLists) //only add lists that have not been released by truck { if (!releaseDocs.Any(x => x.PickupListID == list.Id)) { pickupLists.Add(list); } } } //immediately mark lists that have been downloaded TruckListsDownloaded document = new TruckListsDownloaded(); document.Id = "TRUCKDOWNLOADS_" + truck.Id; document.Name = truck.Id; document.Source = InputSource.TRUCK; document.SyncedToCloud = true; document.Created = DateTime.UtcNow; document.PickupListsDownloaded = new List <string>(); document.PickupListsDownloaded.AddRange(pickupLists.Select(x => x.Id).ToArray()); await DocumentDBContext.UpsertItemAsync <TruckListsDownloaded>(document); var driver = uow.SettingsRepository.GetCurrentDriver(); if (truck == null || driver == null) { return; //only sync if a truck and driver is configured } //pull down clients/farms/fields/trucks and pickuplists Logging.Logger.Log("INFO", "Downloading data."); var clients = await DocumentDBContext.GetAllItemsAsync <ClientEntity>(p => p.EntityType == EntityType.CLIENT && p.Source == InputSource.GIN, 500); var farms = await DocumentDBContext.GetAllItemsAsync <FarmEntity>(p => p.EntityType == EntityType.FARM && p.Source == InputSource.GIN, 500); var fields = await DocumentDBContext.GetAllItemsAsync <FieldEntity>(p => p.EntityType == EntityType.FIELD && p.Source == InputSource.GIN, 500); var trucks = await DocumentDBContext.GetAllItemsAsync <TruckEntity>(p => p.EntityType == EntityType.TRUCK); var drivers = await DocumentDBContext.GetAllItemsAsync <DriverEntity>(p => p.EntityType == EntityType.DRIVER); var syncedSettings = await DocumentDBContext.GetAllItemsAsync <SyncedSettings>(p => p.EntityType == EntityType.SETTING_SUMMARY); var clientIdsToIgnore = new List <string>(); clientIdsToIgnore.Add(GUIDS.UNASSIGNED_CLIENT_ID); var farmIdsToIgnore = new List <string>(); farmIdsToIgnore.Add(GUIDS.UNASSIGNED_FARM_ID); var fieldIdsToIgnore = new List <string>(); fieldIdsToIgnore.Add(GUIDS.UNASSIGNED_FIELD_ID); var listIdsToIgnore = new List <string>(); listIdsToIgnore.Add(GUIDS.UNASSIGNED_LIST_ID); Logging.Logger.Log("INFO", "Fetching local data."); var localClients = uow.ClientRepository.GetAll().Where(c => c.Id != GUIDS.UNASSIGNED_CLIENT_ID); var localFarms = uow.FarmRepository.GetAll().Where(c => c.Id != GUIDS.UNASSIGNED_FARM_ID); var localFields = uow.FieldRepository.GetAll().Where(c => c.Id != GUIDS.UNASSIGNED_FIELD_ID); var localSyncedSettings = uow.SyncedSettingsRepo.GetAll(); var localPickupLists = uow.PickupListRepository.GetAll(new string[] { "DownloadedToTrucks", "AssignedTrucks", "Field.Farm.Client" }).Where(c => c.Id != GUIDS.UNASSIGNED_LIST_ID); var localModules = uow.ModuleRepository.GetAll(new string[] { "Field.Farm.Client", "PickupList" }); var localDrivers = uow.DriverRepository.GetAll(); var localTrucks = uow.TruckRepository.GetAll(); var pickUpListIds = pickupLists.Select(t => t.Id).Distinct().ToArray(); Logging.Logger.Log("INFO", "Fetching modules"); //TODO PICKUPLIST ID var modules = await DocumentDBContext.GetAllItemsAsync <ModuleEntity>(p => p.PickupListId != null && pickUpListIds.Contains(p.PickupListId) && p.EntityType == EntityType.MODULE, 50000); Logging.Logger.Log("INFO", "Computing records to delete."); var fieldsToRemove = localFields.Where(f => !fields.Any(x => x.Id == f.Id)).ToList(); var farmsToRemove = localFarms.Where(f => !farms.Any(x => x.Id == f.Id)).ToList(); var clientsToRemove = localClients.Where(f => !clients.Any(x => x.Id == f.Id)).ToList(); var trucksToRemove = localTrucks.Where(t => !trucks.Any(x => x.Id == t.Id)).ToList(); var driversToRemove = localDrivers.Where(d => !drivers.Any(x => x.Id == d.Id)).ToList(); var listsToRemove = localPickupLists.Where(p => !pickupLists.Any(x => x.Id == p.Id)).ToList(); if (token.IsCancellationRequested) { return; } //if there are items that were deleted at gin but got linked to truck entered data before //truck data was synced then mark records to be sent to gin again to preserve //data integrity if (truck != null && trucksToRemove.Any(t => t.Id == truck.Id)) { truck.Source = InputSource.TRUCK; truck.Updated = DateTime.UtcNow; uow.TruckRepository.Update(truck); uow.SaveChanges(); } if (token.IsCancellationRequested) { return; } if (driver != null && driversToRemove.Any(d => d.Id == driver.Id)) { driver.Source = InputSource.TRUCK; driver.Updated = DateTime.UtcNow; uow.DriverRepository.Update(driver); uow.SaveChanges(); } ///////////// THIS SECTION COULD PROBABLY BE REMOVED SINCE WE ARE PREVENTING DELETE OF LISTS ONCE DOWNLOADED ////////////////////// foreach (var list in listsToRemove) //if list was removed at gin but had modules added, force it to be re-added { bool canDelete = true; var cloudDocument = await DocumentDBContext.GetItemAsync <PickupListEntity>(list.Id); //make sure modules get put back in cloud for reassignment //TODO PICKUPLISTID foreach (var m in localModules.Where(m => m.PickupListId == list.Id)) { var eventsWithSerial = uow.AggregateEventRepository.FindMatching(evt => evt.SerialNumber == m.Name).ToList(); if (eventsWithSerial.Count() > 0) { canDelete = false; m.Source = InputSource.TRUCK; m.Updated = DateTime.UtcNow; uow.ModuleRepository.Update(m); } } //TODO PICKUPLISTID if (localModules.Any(m => m.PickupListId == list.Id) && !canDelete) { list.Source = InputSource.TRUCK; list.Updated = DateTime.UtcNow; uow.PickupListRepository.Update(list); if (cloudDocument != null) //list is in cloud but this truck was removed - add to ignored list to prevent overwriting { listIdsToIgnore.Add(list.Id); } } } uow.SaveChanges(); foreach (var list in localPickupLists.Where(p => p.Source == InputSource.TRUCK)) { if (token.IsCancellationRequested) { return; } var field = localFields.SingleOrDefault(x => x.Id == list.FieldId); if (field != null && fieldsToRemove.Any(x => x.Id == field.Id)) { field.Source = InputSource.TRUCK; field.Updated = DateTime.UtcNow; uow.FieldRepository.Update(field); if (farmsToRemove.Any(x => x.Id == field.FarmId)) { field.Farm.Source = InputSource.TRUCK; field.Updated = DateTime.UtcNow; uow.FarmRepository.Update(field.Farm); } if (clientsToRemove.Any(x => x.Id == field.Farm.Client.Id)) { field.Farm.Client.Source = InputSource.TRUCK; field.Farm.Client.Updated = DateTime.UtcNow; } } } uow.SaveChanges(); ///////////// THE ABOVE SECTION COULD PROBABLY BE REMOVED SINCE WE ARE PREVENTING DELETE OF LISTS ONCE DOWNLOADED ////////////////////// if (token.IsCancellationRequested) { return; } await pushEntitiesOfType <DriverEntity>(uow, uow.DriverRepository, token, drivers, new List <string>()); await pushEntitiesOfType <TruckEntity>(uow, uow.TruckRepository, token, trucks, new List <string>()); await pushEntitiesOfType <ClientEntity>(uow, uow.ClientRepository, token, clients, clientIdsToIgnore); await pushEntitiesOfType <FarmEntity>(uow, uow.FarmRepository, token, farms, farmIdsToIgnore); await pushEntitiesOfType <FieldEntity>(uow, uow.FieldRepository, token, fields, fieldIdsToIgnore); await pushEntitiesOfType <PickupListEntity>(uow, uow.PickupListRepository, token, pickupLists, listIdsToIgnore); await pushModules(uow, uow.ModuleRepository, token, modules); if (token.IsCancellationRequested) { return; } using (var addWork = new UnitOfWork()) { addWork.DisableChangeTracking(); addEntitiesOfType <DriverEntity>(addWork, addWork.DriverRepository, token, drivers, localDrivers); addEntitiesOfType <TruckEntity>(addWork, addWork.TruckRepository, token, trucks, localTrucks); addEntitiesOfType <ClientEntity>(addWork, addWork.ClientRepository, token, clients, localClients); addEntitiesOfType <FarmEntity>(addWork, addWork.FarmRepository, token, farms, localFarms); addEntitiesOfType <FieldEntity>(addWork, addWork.FieldRepository, token, fields, localFields); addEntitiesOfType <PickupListEntity>(addWork, addWork.PickupListRepository, token, pickupLists, localPickupLists); addEntitiesOfType <SyncedSettings>(addWork, addWork.SyncedSettingsRepo, token, syncedSettings, localSyncedSettings); addEntitiesOfType <ModuleEntity>(addWork, addWork.ModuleRepository, token, modules, localModules); } if (token.IsCancellationRequested) { return; } using (var updateWork = new UnitOfWork()) { updateWork.DisableChangeTracking(); updateEntitiesOfType <DriverEntity>(updateWork, updateWork.DriverRepository, token, drivers, localDrivers, false); updateEntitiesOfType <TruckEntity>(updateWork, updateWork.TruckRepository, token, trucks, localTrucks, true); updateEntitiesOfType <ClientEntity>(updateWork, updateWork.ClientRepository, token, clients, localClients, false); updateEntitiesOfType <FarmEntity>(updateWork, updateWork.FarmRepository, token, farms, localFarms, false); updateEntitiesOfType <FieldEntity>(updateWork, updateWork.FieldRepository, token, fields, localFields, false); updateEntitiesOfType <PickupListEntity>(updateWork, updateWork.PickupListRepository, token, pickupLists, localPickupLists, false); updateEntitiesOfTypeIfNewer <ModuleEntity>(updateWork, updateWork.ModuleRepository, token, modules, localModules, false); updateEntitiesOfType <SyncedSettings>(updateWork, updateWork.SyncedSettingsRepo, token, syncedSettings, localSyncedSettings, false); } if (token.IsCancellationRequested) { return; } deleteEntitiesOfType <DriverEntity>(uow, uow.DriverRepository, token, drivers); deleteEntitiesOfType <TruckEntity>(uow, uow.TruckRepository, token, trucks); deleteEntitiesOfType <ModuleEntity>(uow, uow.ModuleRepository, token, modules); deleteEntitiesOfType <PickupListEntity>(uow, uow.PickupListRepository, token, pickupLists); deleteEntitiesOfType <FieldEntity>(uow, uow.FieldRepository, token, fields); deleteEntitiesOfType <FarmEntity>(uow, uow.FarmRepository, token, farms); deleteEntitiesOfType <ClientEntity>(uow, uow.ClientRepository, token, clients); cleanDupedModules(uow, uow.ModuleRepository, token); if (truck != null) { //send aggregate events to cloud Logging.Logger.Log("INFO", "Send aggregate events"); foreach (var moduleEvent in uow.AggregateEventRepository.GetDirtyOrderedByTime()) { if (token.IsCancellationRequested) { return; } if (truck != null) { moduleEvent.TruckID = truck.Id; } if (driver != null) { moduleEvent.DriverID = driver.Id; } moduleEvent.Source = InputSource.TRUCK; //lookup module var module = uow.ModuleRepository.FindSingle(m => m.Name == moduleEvent.SerialNumber, "Field.Farm.Client", "PickupList"); //add on field/farm/client/pickup list info it may be needed to re-create list at gin if (module != null) { moduleEvent.PickupListId = module.PickupListId; moduleEvent.PickupListName = module.ListName; if (module.Field != null) { moduleEvent.FarmId = module.Field.FarmId; } moduleEvent.FarmName = module.FarmName; moduleEvent.FieldId = module.FieldId; moduleEvent.FieldName = module.FieldName; moduleEvent.ModuleId = module.Id; if (module.Field.Farm != null) { moduleEvent.ClientId = module.Field.Farm.ClientId; } moduleEvent.ClientName = module.ClientName; } await DocumentDBContext.UpsertItemAsync <AggregateEvent>(moduleEvent); uow.AggregateEventRepository.Update(moduleEvent, true); uow.SaveChanges(); } if (token.IsCancellationRequested) { return; } //send list of pickup lists this truck has Logging.Logger.Log("INFO", "Send list of pickup lists this truck has downloaded."); var lists = uow.PickupListRepository.FindMatching(t => t.AssignedTrucks.Any(x => x.Id == truck.Id), new string[] { "AssignedTrucks" }); TruckListsDownloaded document2 = new TruckListsDownloaded(); document2.Id = "TRUCKDOWNLOADS_" + truck.Id; document2.Name = truck.Id; document2.Source = InputSource.TRUCK; document2.SyncedToCloud = true; document2.Created = DateTime.UtcNow; document2.PickupListsDownloaded = new List <string>(); document2.PickupListsDownloaded.AddRange(lists.Select(x => x.Id).ToArray()); await DocumentDBContext.UpsertItemAsync <TruckListsDownloaded>(document2); } } catch (Exception exc) { Logging.Logger.Log(exc); } } } } catch (Exception outerExc) { Logging.Logger.Log(outerExc); } }