private bool UpdateDocumentsUsage(long?maxId = null)
        {
            if (numbersUsagePerLocation == null ||
                numbersUsageStarts == null)
            {
                return(false);
            }

            if (maxId == null)
            {
                maxId = Operation.GetMaxId();
            }

            hasEmptyRange = false;

            for (int i = 0; i < allStartNumbersPerLocation.Count; i++)
            {
                foreach (OperationNumberingInfo numberingInfo in allStartNumbersPerLocation[i].Value)
                {
                    long endNumber = maxId.Value;
                    long endRange  = endNumber;
                    if (i + 1 < allStartNumbersPerLocation.Count)
                    {
                        OperationNumberingInfo nextInfo = allStartNumbersPerLocation [i + 1].Value.FirstOrDefault(n => n.OperationType == numberingInfo.OperationType);
                        if (nextInfo != null)
                        {
                            endRange = nextInfo.StartNumber - 1;
                            if (nextInfo.StartNumber > 0)
                            {
                                endNumber = nextInfo.StartNumber - 1;
                            }
                        }
                    }

                    long usedNumbers            = 0;
                    long startNumber            = numberingInfo.StartNumber + 1;
                    OperationNumbersUsage usage = numbersUsagePerLocation.FirstOrDefault(n => numberingInfo.LocationId == n.LocationId && numberingInfo.OperationType == n.OperationType);
                    if (usage != null)
                    {
                        usedNumbers = usage.UsedNumbers;
                        startNumber = Math.Max(startNumber, usage.LastUsedNumber);
                    }

                    ObjectsContainer <OperationType, long> firtNextNumber = numbersUsageStarts.FirstOrDefault(n => numberingInfo.StartNumber < n.Value2 && numberingInfo.OperationType == n.Value1);
                    if (firtNextNumber != null)
                    {
                        endNumber = Math.Min(endNumber, firtNextNumber.Value2 - 1);
                    }

                    double numbersLeft = Math.Max(endNumber - startNumber, 0);
                    if (numbersLeft < OperationNumberingInfo.MINIMAL_NUMBERS_PER_LOCATION)
                    {
                        hasEmptyRange = true;
                    }

                    long rangeSize = Math.Max(endRange - numberingInfo.StartNumber, 0);
                    if (rangeSize == 0)
                    {
                        MessageError.ShowDialog(string.Format(Translator.GetString("The selected numbers parameters are not valid! Please select ranges which will generate document numbers lower than {0}."), maxId.Value.ToString("N", formatBigNumber)));
                        throw new ArgumentOutOfRangeException();
                    }

                    numberingInfo.Usage            = (rangeSize - numbersLeft) / rangeSize;
                    numberingInfo.UsageDescription = string.Format(Translator.GetString("{0} used, {1} left"),
                                                                   usedNumbers.ToString("N", formatBigNumber),
                                                                   numbersLeft.ToString("N", formatBigNumber));
                }
            }

            frmMessage.Visible = hasEmptyRange;

            IListModel model = gridDocumentNumbers.Model;

            gridDocumentNumbers.Model = null;
            gridDocumentNumbers.Model = model;
            return(true);
        }
        private void InitializeLocationsGrid()
        {
            gridLocations = new ListView
            {
                Name                = "gridLocations",
                WidthRequest        = 250,
                HeightRequest       = 400,
                AllowMultipleSelect = false
            };
            gridLocations.Selection.Changed += Selection_Changed;

            gridLocations.ColumnController = new ColumnController
            {
                new Column(Translator.GetString("Location"), "Name", 1, "Name")
            };

            scwLocations.Add(gridLocations);
            gridLocations.Show();

            allLocations = Location.GetAll();

            bool recreated = false;
            bool retry;

            do
            {
                retry           = false;
                allStartNumbers = OperationNumberingInfo.Get();
                if (allStartNumbers.Length == 0)
                {
                    OperationNumberingInfo.Create();
                    recreated       = true;
                    allStartNumbers = OperationNumberingInfo.Get();
                }
                allStartNumbersPerLocation.Clear();

                foreach (Location location in allLocations)
                {
                    Location l = location;
                    List <OperationNumberingInfo> operations = allStartNumbers.Where(o => o.LocationId == l.Id).ToList();
                    if (operations.Count == 0 && !recreated)
                    {
                        OperationNumberingInfo.Create();
                        retry     = true;
                        recreated = true;
                        break;
                    }

                    foreach (var info in operations)
                    {
                        info.UsageDescription = Translator.GetString("Calculating...");
                    }

                    allStartNumbersPerLocation.Add(new KeyValuePair <long, BindingListModel <OperationNumberingInfo> > (location.Id,
                                                                                                                        new BindingListModel <OperationNumberingInfo> (operations)));
                }
            } while (retry);

            DataHelper.FireAndForget(() =>
            {
                numbersUsagePerLocation = OperationNumbersUsage.Get();
                numbersUsageStarts      = OperationNumbersUsage.GetUsagesStarts();
                Timeout.Add(0, () =>
                {
                    try {
                        UpdateDocumentsUsage();
                    } catch (ArgumentOutOfRangeException) { }
                    return(false);
                });
            });

            allStartNumbersPerLocation = allStartNumbersPerLocation.OrderBy(p => p.Value.Min(o => o.StartNumber)).ToList();
            // Use a model with natural order by the operation number intervals
            gridLocations.Model = new BindingListModel <Location> (allStartNumbersPerLocation.Select(d => allLocations.Find(p => p.Id == d.Key)));
            lblCurrentLocationsValue.SetText(allLocations.Count.ToString("N", formatBigNumber));

            if (gridLocations.Model.Count <= 0)
            {
                return;
            }

            gridLocations.FocusRow(0);
            gridLocations.Selection.Select(0);
            gridLocations.ScrollToV(0);
        }