edit
This commit is contained in:
@@ -9,6 +9,8 @@ namespace XLAB
|
|||||||
|
|
||||||
IReadOnlyList<AvailableInstrumentItem> ShowInstrumentPickerDialog(string customerName, IReadOnlyList<AvailableInstrumentItem> instruments);
|
IReadOnlyList<AvailableInstrumentItem> ShowInstrumentPickerDialog(string customerName, IReadOnlyList<AvailableInstrumentItem> instruments);
|
||||||
|
|
||||||
|
InstrumentTypeSelectionResult ShowInstrumentTypeDialog(string customerName, IReadOnlyList<AvailableInstrumentItem> instrumentTypes);
|
||||||
|
|
||||||
VerificationEditResult ShowVerificationDialog(
|
VerificationEditResult ShowVerificationDialog(
|
||||||
VerificationEditSeed seed,
|
VerificationEditSeed seed,
|
||||||
IReadOnlyList<PersonReference> verifiers,
|
IReadOnlyList<PersonReference> verifiers,
|
||||||
@@ -52,6 +54,16 @@ namespace XLAB
|
|||||||
return result.HasValue && result.Value ? viewModel.GetSelectedItems() : null;
|
return result.HasValue && result.Value ? viewModel.GetSelectedItems() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public InstrumentTypeSelectionResult ShowInstrumentTypeDialog(string customerName, IReadOnlyList<AvailableInstrumentItem> instrumentTypes)
|
||||||
|
{
|
||||||
|
var viewModel = new SelectInstrumentTypeWindowViewModel(customerName, instrumentTypes);
|
||||||
|
var window = new SelectInstrumentTypeWindow(viewModel);
|
||||||
|
window.Owner = _owner;
|
||||||
|
|
||||||
|
var result = window.ShowDialog();
|
||||||
|
return result.HasValue && result.Value ? viewModel.GetResult() : null;
|
||||||
|
}
|
||||||
|
|
||||||
public VerificationEditResult ShowVerificationDialog(
|
public VerificationEditResult ShowVerificationDialog(
|
||||||
VerificationEditSeed seed,
|
VerificationEditSeed seed,
|
||||||
IReadOnlyList<PersonReference> verifiers,
|
IReadOnlyList<PersonReference> verifiers,
|
||||||
|
|||||||
@@ -198,6 +198,8 @@
|
|||||||
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
|
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
|
||||||
<MenuItem Header="Добавить по заводским номерам"
|
<MenuItem Header="Добавить по заводским номерам"
|
||||||
Command="{Binding OpenInstrumentPickerCommand}" />
|
Command="{Binding OpenInstrumentPickerCommand}" />
|
||||||
|
<MenuItem Header="Добавить по типу"
|
||||||
|
Command="{Binding OpenInstrumentTypePickerCommand}" />
|
||||||
<MenuItem Header="Удалить"
|
<MenuItem Header="Удалить"
|
||||||
Command="{Binding DeleteSelectedGroupsCommand}" />
|
Command="{Binding DeleteSelectedGroupsCommand}" />
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ namespace XLAB
|
|||||||
MarkLinePassedCommand = new RelayCommand(delegate { EditLineVerificationAsync(true); }, delegate { return CanEditSelectedLineVerification(); });
|
MarkLinePassedCommand = new RelayCommand(delegate { EditLineVerificationAsync(true); }, delegate { return CanEditSelectedLineVerification(); });
|
||||||
MarkLineRejectedCommand = new RelayCommand(delegate { EditLineVerificationAsync(false); }, delegate { return CanEditSelectedLineVerification(); });
|
MarkLineRejectedCommand = new RelayCommand(delegate { EditLineVerificationAsync(false); }, delegate { return CanEditSelectedLineVerification(); });
|
||||||
OpenInstrumentPickerCommand = new RelayCommand(delegate { OpenInstrumentPickerAsync(); }, delegate { return !IsBusy && SelectedDocument != null && SelectedDocument.CustomerId.HasValue; });
|
OpenInstrumentPickerCommand = new RelayCommand(delegate { OpenInstrumentPickerAsync(); }, delegate { return !IsBusy && SelectedDocument != null && SelectedDocument.CustomerId.HasValue; });
|
||||||
|
OpenInstrumentTypePickerCommand = new RelayCommand(delegate { OpenInstrumentTypePickerAsync(); }, delegate { return !IsBusy && SelectedDocument != null && SelectedDocument.CustomerId.HasValue; });
|
||||||
RefreshDocumentsCommand = new RelayCommand(delegate { RefreshDocumentsAsync(null, null); }, delegate { return !IsBusy; });
|
RefreshDocumentsCommand = new RelayCommand(delegate { RefreshDocumentsAsync(null, null); }, delegate { return !IsBusy; });
|
||||||
ResetLineVerificationCommand = new RelayCommand(delegate { ResetSelectedLineVerificationAsync(); }, delegate { return CanResetSelectedLineVerification(); });
|
ResetLineVerificationCommand = new RelayCommand(delegate { ResetSelectedLineVerificationAsync(); }, delegate { return CanResetSelectedLineVerification(); });
|
||||||
SaveDocumentHeaderCommand = new RelayCommand(delegate { SaveDocumentAsync(); }, delegate { return CanSaveDocument(); });
|
SaveDocumentHeaderCommand = new RelayCommand(delegate { SaveDocumentAsync(); }, delegate { return CanSaveDocument(); });
|
||||||
@@ -169,6 +170,8 @@ namespace XLAB
|
|||||||
|
|
||||||
public ICommand OpenInstrumentPickerCommand { get; private set; }
|
public ICommand OpenInstrumentPickerCommand { get; private set; }
|
||||||
|
|
||||||
|
public ICommand OpenInstrumentTypePickerCommand { get; private set; }
|
||||||
|
|
||||||
public ICommand RefreshDocumentsCommand { get; private set; }
|
public ICommand RefreshDocumentsCommand { get; private set; }
|
||||||
|
|
||||||
public ICommand ResetLineVerificationCommand { get; private set; }
|
public ICommand ResetLineVerificationCommand { get; private set; }
|
||||||
@@ -513,12 +516,141 @@ namespace XLAB
|
|||||||
&& source.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0;
|
&& source.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string BuildOpenDocumentConflictMessage(IEnumerable<OpenDocumentConflictInfo> conflicts)
|
||||||
|
{
|
||||||
|
var materializedConflicts = NormalizeOpenDocumentConflicts(conflicts);
|
||||||
|
if (materializedConflicts.Count == 0)
|
||||||
|
{
|
||||||
|
return "Прибор уже находится в другой открытой ПСВ этого заказчика.";
|
||||||
|
}
|
||||||
|
|
||||||
|
var preview = materializedConflicts
|
||||||
|
.Take(5)
|
||||||
|
.Select(delegate(OpenDocumentConflictInfo conflict)
|
||||||
|
{
|
||||||
|
return string.Format("зав. № {0} -> {1}", conflict.SerialNumber, conflict.DocumentNumber);
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var suffix = materializedConflicts.Count > preview.Count
|
||||||
|
? string.Format(" Еще конфликтов: {0}.", materializedConflicts.Count - preview.Count)
|
||||||
|
: string.Empty;
|
||||||
|
|
||||||
|
return string.Format(
|
||||||
|
"Приборы уже находятся в других открытых ПСВ этого заказчика: {0}.{1}",
|
||||||
|
string.Join("; ", preview.ToArray()),
|
||||||
|
suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<OpenDocumentConflictInfo> FindOpenDocumentConflicts(IEnumerable<PsvDocumentLine> candidateLines)
|
||||||
|
{
|
||||||
|
if (SelectedDocument == null || !SelectedDocument.CustomerId.HasValue || candidateLines == null)
|
||||||
|
{
|
||||||
|
return new List<OpenDocumentConflictInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var conflicts = FindPendingOpenDocumentConflicts(SelectedDocument, candidateLines);
|
||||||
|
conflicts.AddRange(_service.FindOpenDocumentConflicts(
|
||||||
|
SelectedDocument.CustomerId.Value,
|
||||||
|
SelectedDocument.IsDraft ? null : SelectedDocument.DocumentNumber,
|
||||||
|
candidateLines));
|
||||||
|
|
||||||
|
return NormalizeOpenDocumentConflicts(conflicts);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<OpenDocumentConflictInfo> FindPendingOpenDocumentConflicts(PsvDocumentSummary currentDocument, IEnumerable<PsvDocumentLine> candidateLines)
|
||||||
|
{
|
||||||
|
if (currentDocument == null || !currentDocument.CustomerId.HasValue || candidateLines == null)
|
||||||
|
{
|
||||||
|
return new List<OpenDocumentConflictInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var candidateKeys = new HashSet<string>(
|
||||||
|
candidateLines
|
||||||
|
.Where(delegate(PsvDocumentLine line)
|
||||||
|
{
|
||||||
|
return line != null
|
||||||
|
&& line.TypeSizeId > 0
|
||||||
|
&& !string.IsNullOrWhiteSpace(line.SerialNumber);
|
||||||
|
})
|
||||||
|
.Select(delegate(PsvDocumentLine line) { return line.OpenDocumentConflictKey; }),
|
||||||
|
StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
if (candidateKeys.Count == 0)
|
||||||
|
{
|
||||||
|
return new List<OpenDocumentConflictInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var conflicts = new List<OpenDocumentConflictInfo>();
|
||||||
|
|
||||||
|
foreach (var pendingLinesByDocument in _pendingLinesByDocumentKey)
|
||||||
|
{
|
||||||
|
if (string.Equals(pendingLinesByDocument.Key, currentDocument.DocumentKey, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var otherDocument = Documents.FirstOrDefault(delegate(PsvDocumentSummary document)
|
||||||
|
{
|
||||||
|
return string.Equals(document.DocumentKey, pendingLinesByDocument.Key, StringComparison.OrdinalIgnoreCase);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (otherDocument == null
|
||||||
|
|| !otherDocument.CustomerId.HasValue
|
||||||
|
|| otherDocument.CustomerId.Value != currentDocument.CustomerId.Value)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var otherLine in pendingLinesByDocument.Value.Where(delegate(PsvDocumentLine line)
|
||||||
|
{
|
||||||
|
return line != null
|
||||||
|
&& line.TypeSizeId > 0
|
||||||
|
&& !string.IsNullOrWhiteSpace(line.SerialNumber);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
if (!candidateKeys.Contains(otherLine.OpenDocumentConflictKey))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
conflicts.Add(new OpenDocumentConflictInfo
|
||||||
|
{
|
||||||
|
DocumentNumber = otherDocument.DocumentNumber,
|
||||||
|
TypeSizeId = otherLine.TypeSizeId,
|
||||||
|
SerialNumber = otherLine.SerialNumber
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NormalizeOpenDocumentConflicts(conflicts);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<OpenDocumentConflictInfo> NormalizeOpenDocumentConflicts(IEnumerable<OpenDocumentConflictInfo> conflicts)
|
||||||
|
{
|
||||||
|
return (conflicts ?? Enumerable.Empty<OpenDocumentConflictInfo>())
|
||||||
|
.Where(delegate(OpenDocumentConflictInfo conflict) { return conflict != null; })
|
||||||
|
.GroupBy(delegate(OpenDocumentConflictInfo conflict)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
"{0}|{1}|{2}",
|
||||||
|
conflict.DocumentNumber ?? string.Empty,
|
||||||
|
conflict.TypeSizeId,
|
||||||
|
conflict.SerialNumber ?? string.Empty);
|
||||||
|
}, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.Select(delegate(IGrouping<string, OpenDocumentConflictInfo> group) { return group.First(); })
|
||||||
|
.OrderBy(delegate(OpenDocumentConflictInfo conflict) { return conflict.SerialNumber ?? string.Empty; })
|
||||||
|
.ThenBy(delegate(OpenDocumentConflictInfo conflict) { return conflict.DocumentNumber ?? string.Empty; })
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
private PsvDocumentLine CreatePendingLine(AvailableInstrumentItem item)
|
private PsvDocumentLine CreatePendingLine(AvailableInstrumentItem item)
|
||||||
{
|
{
|
||||||
return new PsvDocumentLine
|
return new PsvDocumentLine
|
||||||
{
|
{
|
||||||
CardId = 0,
|
CardId = 0,
|
||||||
InstrumentId = item.InstrumentId,
|
InstrumentId = item.InstrumentId,
|
||||||
|
TypeSizeId = item.TypeSizeId,
|
||||||
SerialNumber = item.SerialNumber,
|
SerialNumber = item.SerialNumber,
|
||||||
InventoryNumber = item.InventoryNumber,
|
InventoryNumber = item.InventoryNumber,
|
||||||
CustomerName = item.CustomerName,
|
CustomerName = item.CustomerName,
|
||||||
@@ -547,6 +679,41 @@ namespace XLAB
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PsvDocumentLine CreatePendingTypeLine(AvailableInstrumentItem item, string serialNumber)
|
||||||
|
{
|
||||||
|
return new PsvDocumentLine
|
||||||
|
{
|
||||||
|
CardId = 0,
|
||||||
|
InstrumentId = 0,
|
||||||
|
TypeSizeId = item.TypeSizeId,
|
||||||
|
SerialNumber = string.IsNullOrWhiteSpace(serialNumber) ? string.Empty : serialNumber.Trim(),
|
||||||
|
InventoryNumber = string.Empty,
|
||||||
|
CustomerName = SelectedDocument == null ? string.Empty : SelectedDocument.CustomerName,
|
||||||
|
InstrumentType = item.InstrumentType,
|
||||||
|
InstrumentName = item.InstrumentName,
|
||||||
|
MeasurementArea = item.MeasurementArea,
|
||||||
|
RangeText = item.RangeText,
|
||||||
|
RegistryNumber = item.RegistryNumber,
|
||||||
|
AccuracyText = item.AccuracyText,
|
||||||
|
VerificationType = string.Empty,
|
||||||
|
PeriodMonths = 0,
|
||||||
|
AcceptedOn = HeaderReceivedOn,
|
||||||
|
IssuedOn = null,
|
||||||
|
IsPassed = null,
|
||||||
|
VerificationPerformedOn = null,
|
||||||
|
VerifierId = null,
|
||||||
|
VerifierName = string.Empty,
|
||||||
|
StickerNumber = string.Empty,
|
||||||
|
VerificationDocumentFormId = null,
|
||||||
|
VerificationDocumentLinkTypeId = null,
|
||||||
|
VerificationDocumentNumber = string.Empty,
|
||||||
|
VerificationDocumentDate = null,
|
||||||
|
RejectionReason = string.Empty,
|
||||||
|
Notes = string.Empty,
|
||||||
|
IsPendingInsert = true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static void ApplyVerificationResultCore(PsvDocumentLine line, VerificationEditResult result)
|
private static void ApplyVerificationResultCore(PsvDocumentLine line, VerificationEditResult result)
|
||||||
{
|
{
|
||||||
if (line == null || result == null)
|
if (line == null || result == null)
|
||||||
@@ -1146,6 +1313,50 @@ namespace XLAB
|
|||||||
AddSelectedInstruments(selectedItems);
|
AddSelectedInstruments(selectedItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OpenInstrumentTypePickerAsync()
|
||||||
|
{
|
||||||
|
if (SelectedDocument == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SelectedDocument.CustomerId.HasValue)
|
||||||
|
{
|
||||||
|
_dialogService.ShowWarning("Сначала выберите заказчика в ПСВ.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenInstrumentTypePickerCoreAsync(SelectedDocument.CustomerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OpenInstrumentTypePickerCoreAsync(string customerName)
|
||||||
|
{
|
||||||
|
IReadOnlyList<AvailableInstrumentItem> instrumentTypes;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IsBusy = true;
|
||||||
|
instrumentTypes = await Task.Run(delegate { return _service.LoadInstrumentTypes(); });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_dialogService.ShowError(ex.Message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IsBusy = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = _dialogService.ShowInstrumentTypeDialog(customerName, instrumentTypes);
|
||||||
|
if (result == null || result.TypeItem == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddSelectedTypeInstrument(result);
|
||||||
|
}
|
||||||
|
|
||||||
private void AddSelectedInstruments(IReadOnlyList<AvailableInstrumentItem> selectedItems)
|
private void AddSelectedInstruments(IReadOnlyList<AvailableInstrumentItem> selectedItems)
|
||||||
{
|
{
|
||||||
if (SelectedDocument == null)
|
if (SelectedDocument == null)
|
||||||
@@ -1160,13 +1371,45 @@ namespace XLAB
|
|||||||
_pendingLinesByDocumentKey[SelectedDocument.DocumentKey] = pendingLines;
|
_pendingLinesByDocumentKey[SelectedDocument.DocumentKey] = pendingLines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var candidateLines = selectedItems
|
||||||
|
.Where(delegate(AvailableInstrumentItem item) { return item != null; })
|
||||||
|
.Select(CreatePendingLine)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
List<OpenDocumentConflictInfo> openDocumentConflicts;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
openDocumentConflicts = FindOpenDocumentConflicts(candidateLines);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_dialogService.ShowError(ex.Message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var openConflictKeys = new HashSet<string>(
|
||||||
|
openDocumentConflicts.Select(delegate(OpenDocumentConflictInfo conflict) { return conflict.OpenDocumentConflictKey; }),
|
||||||
|
StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
var duplicateKeys = new HashSet<string>(DocumentLines.Select(delegate(PsvDocumentLine line) { return line.DuplicateKey; }), StringComparer.OrdinalIgnoreCase);
|
var duplicateKeys = new HashSet<string>(DocumentLines.Select(delegate(PsvDocumentLine line) { return line.DuplicateKey; }), StringComparer.OrdinalIgnoreCase);
|
||||||
var addedCount = 0;
|
var addedCount = 0;
|
||||||
var skippedDuplicateCount = 0;
|
var skippedDuplicateCount = 0;
|
||||||
|
var skippedOpenDocumentCount = 0;
|
||||||
var skippedWithoutTemplateCount = 0;
|
var skippedWithoutTemplateCount = 0;
|
||||||
|
|
||||||
foreach (var item in selectedItems)
|
foreach (var item in selectedItems)
|
||||||
{
|
{
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (openConflictKeys.Contains(PsvDocumentLine.BuildOpenDocumentConflictKey(item.TypeSizeId, item.SerialNumber)))
|
||||||
|
{
|
||||||
|
skippedOpenDocumentCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!item.HasTemplate)
|
if (!item.HasTemplate)
|
||||||
{
|
{
|
||||||
skippedWithoutTemplateCount++;
|
skippedWithoutTemplateCount++;
|
||||||
@@ -1208,11 +1451,98 @@ namespace XLAB
|
|||||||
messages.Add(string.Format("Пропущено без шаблона EKZMK: {0}.", skippedWithoutTemplateCount));
|
messages.Add(string.Format("Пропущено без шаблона EKZMK: {0}.", skippedWithoutTemplateCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messages.Count > 0)
|
if (skippedOpenDocumentCount > 0)
|
||||||
{
|
{
|
||||||
_dialogService.ShowInfo(string.Join(" ", messages.ToArray()));
|
messages.Add(string.Format("Пропущено из-за других открытых ПСВ: {0}.", skippedOpenDocumentCount));
|
||||||
|
messages.Add(BuildOpenDocumentConflictMessage(openDocumentConflicts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (messages.Count > 0)
|
||||||
|
{
|
||||||
|
var message = string.Join(" ", messages.ToArray());
|
||||||
|
if (addedCount == 0 && skippedOpenDocumentCount > 0)
|
||||||
|
{
|
||||||
|
_dialogService.ShowWarning(message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_dialogService.ShowInfo(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RaiseCommandStates();
|
||||||
|
OnPropertyChanged("IsCustomerEditable");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddSelectedTypeInstrument(InstrumentTypeSelectionResult result)
|
||||||
|
{
|
||||||
|
if (SelectedDocument == null || result == null || result.TypeItem == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PsvDocumentLine> pendingLines;
|
||||||
|
if (!_pendingLinesByDocumentKey.TryGetValue(SelectedDocument.DocumentKey, out pendingLines))
|
||||||
|
{
|
||||||
|
pendingLines = new List<PsvDocumentLine>();
|
||||||
|
_pendingLinesByDocumentKey[SelectedDocument.DocumentKey] = pendingLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
var serialNumber = string.IsNullOrWhiteSpace(result.SerialNumber) ? string.Empty : result.SerialNumber.Trim();
|
||||||
|
if (string.IsNullOrWhiteSpace(serialNumber))
|
||||||
|
{
|
||||||
|
_dialogService.ShowWarning("Введите заводской номер.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.TypeItem.HasTemplate)
|
||||||
|
{
|
||||||
|
_dialogService.ShowWarning("Выбранный тип нельзя добавить: для него не найден шаблон EKZMK или период МК.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var candidateLine = CreatePendingTypeLine(result.TypeItem, serialNumber);
|
||||||
|
List<OpenDocumentConflictInfo> openDocumentConflicts;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
openDocumentConflicts = FindOpenDocumentConflicts(new[] { candidateLine });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_dialogService.ShowError(ex.Message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (openDocumentConflicts.Count > 0)
|
||||||
|
{
|
||||||
|
_dialogService.ShowWarning(BuildOpenDocumentConflictMessage(openDocumentConflicts));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var duplicateKey = PsvDocumentLine.BuildDuplicateKey(
|
||||||
|
result.TypeItem.InstrumentType,
|
||||||
|
result.TypeItem.RangeText,
|
||||||
|
result.TypeItem.RegistryNumber,
|
||||||
|
serialNumber);
|
||||||
|
|
||||||
|
if (DocumentLines.Any(delegate(PsvDocumentLine line)
|
||||||
|
{
|
||||||
|
return string.Equals(line.DuplicateKey, duplicateKey, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
_dialogService.ShowWarning("Такой прибор уже есть в ПСВ.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingLines.Add(candidateLine);
|
||||||
|
|
||||||
|
if (SelectedDocument.IsDraft)
|
||||||
|
{
|
||||||
|
SelectedDocument.ItemCount = pendingLines.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadSelectedDocumentAsync();
|
||||||
|
_dialogService.ShowInfo("Прибор по типу добавлен в ПСВ.");
|
||||||
RaiseCommandStates();
|
RaiseCommandStates();
|
||||||
OnPropertyChanged("IsCustomerEditable");
|
OnPropertyChanged("IsCustomerEditable");
|
||||||
}
|
}
|
||||||
@@ -1254,6 +1584,7 @@ namespace XLAB
|
|||||||
((RelayCommand)MarkLinePassedCommand).RaiseCanExecuteChanged();
|
((RelayCommand)MarkLinePassedCommand).RaiseCanExecuteChanged();
|
||||||
((RelayCommand)MarkLineRejectedCommand).RaiseCanExecuteChanged();
|
((RelayCommand)MarkLineRejectedCommand).RaiseCanExecuteChanged();
|
||||||
((RelayCommand)OpenInstrumentPickerCommand).RaiseCanExecuteChanged();
|
((RelayCommand)OpenInstrumentPickerCommand).RaiseCanExecuteChanged();
|
||||||
|
((RelayCommand)OpenInstrumentTypePickerCommand).RaiseCanExecuteChanged();
|
||||||
((RelayCommand)RefreshDocumentsCommand).RaiseCanExecuteChanged();
|
((RelayCommand)RefreshDocumentsCommand).RaiseCanExecuteChanged();
|
||||||
((RelayCommand)ResetLineVerificationCommand).RaiseCanExecuteChanged();
|
((RelayCommand)ResetLineVerificationCommand).RaiseCanExecuteChanged();
|
||||||
((RelayCommand)SaveDocumentHeaderCommand).RaiseCanExecuteChanged();
|
((RelayCommand)SaveDocumentHeaderCommand).RaiseCanExecuteChanged();
|
||||||
@@ -1398,7 +1729,12 @@ namespace XLAB
|
|||||||
}
|
}
|
||||||
|
|
||||||
var pendingLines = GetPendingLines(SelectedDocument)
|
var pendingLines = GetPendingLines(SelectedDocument)
|
||||||
.Where(delegate(PsvDocumentLine line) { return line.InstrumentId > 0; })
|
.Where(delegate(PsvDocumentLine line)
|
||||||
|
{
|
||||||
|
return line != null
|
||||||
|
&& (line.InstrumentId > 0
|
||||||
|
|| (line.TypeSizeId > 0 && !string.IsNullOrWhiteSpace(line.SerialNumber)));
|
||||||
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
if (SelectedDocument.IsDraft && pendingLines.Count == 0)
|
if (SelectedDocument.IsDraft && pendingLines.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -1406,11 +1742,19 @@ namespace XLAB
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var openDocumentConflicts = FindPendingOpenDocumentConflicts(SelectedDocument, pendingLines);
|
||||||
|
if (openDocumentConflicts.Count > 0)
|
||||||
|
{
|
||||||
|
_dialogService.ShowWarning(BuildOpenDocumentConflictMessage(openDocumentConflicts));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var request = new DocumentEditorResult
|
var request = new DocumentEditorResult
|
||||||
{
|
{
|
||||||
DocumentNumber = DocumentNumberEditor.Trim(),
|
DocumentNumber = DocumentNumberEditor.Trim(),
|
||||||
AcceptedOn = HeaderReceivedOn.Value,
|
AcceptedOn = HeaderReceivedOn.Value,
|
||||||
IssuedOn = HeaderIssuedOn
|
IssuedOn = HeaderIssuedOn,
|
||||||
|
CustomerId = SelectedDocument.CustomerId ?? SelectedCustomerId
|
||||||
};
|
};
|
||||||
|
|
||||||
var currentDocumentNumber = SelectedDocument.IsDraft ? null : SelectedDocument.DocumentNumber;
|
var currentDocumentNumber = SelectedDocument.IsDraft ? null : SelectedDocument.DocumentNumber;
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ ORDER BY MAX(m.DTPRM) DESC, m.NNZVPV DESC;";
|
|||||||
SELECT
|
SELECT
|
||||||
m.IDEKZMK AS CardId,
|
m.IDEKZMK AS CardId,
|
||||||
z.IDEKZ AS InstrumentId,
|
z.IDEKZ AS InstrumentId,
|
||||||
|
z.IDTPRZ AS TypeSizeId,
|
||||||
z.NNZV AS SerialNumber,
|
z.NNZV AS SerialNumber,
|
||||||
z.NNIN AS InventoryNumber,
|
z.NNIN AS InventoryNumber,
|
||||||
ownerOrg.NMFRPD AS CustomerName,
|
ownerOrg.NMFRPD AS CustomerName,
|
||||||
@@ -279,6 +280,7 @@ ORDER BY areas.NMOI, names.NMTP, tips.TP, z.NNZV;";
|
|||||||
{
|
{
|
||||||
CardId = GetInt32(reader, "CardId"),
|
CardId = GetInt32(reader, "CardId"),
|
||||||
InstrumentId = GetInt32(reader, "InstrumentId"),
|
InstrumentId = GetInt32(reader, "InstrumentId"),
|
||||||
|
TypeSizeId = GetInt32(reader, "TypeSizeId"),
|
||||||
SerialNumber = GetString(reader, "SerialNumber"),
|
SerialNumber = GetString(reader, "SerialNumber"),
|
||||||
InventoryNumber = GetString(reader, "InventoryNumber"),
|
InventoryNumber = GetString(reader, "InventoryNumber"),
|
||||||
CustomerName = GetString(reader, "CustomerName"),
|
CustomerName = GetString(reader, "CustomerName"),
|
||||||
@@ -425,6 +427,109 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, z.NNZV;";
|
|||||||
return instruments;
|
return instruments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IReadOnlyList<AvailableInstrumentItem> LoadInstrumentTypes()
|
||||||
|
{
|
||||||
|
const string sql = @"
|
||||||
|
SELECT
|
||||||
|
0 AS InstrumentId,
|
||||||
|
sizeInfo.IDTPRZ AS TypeSizeId,
|
||||||
|
CAST(N'' AS nvarchar(30)) AS SerialNumber,
|
||||||
|
CAST(N'' AS nvarchar(30)) AS InventoryNumber,
|
||||||
|
CAST(N'' AS nvarchar(255)) AS CustomerName,
|
||||||
|
tips.TP AS InstrumentType,
|
||||||
|
names.NMTP AS InstrumentName,
|
||||||
|
areas.NMOI AS MeasurementArea,
|
||||||
|
sizeInfo.NNGSRS AS RegistryNumber,
|
||||||
|
sizeInfo.DPZN AS RangeText,
|
||||||
|
sizeInfo.HRTC AS AccuracyText,
|
||||||
|
CASE
|
||||||
|
WHEN typeTemplate.LastDocumentNumber IS NOT NULL
|
||||||
|
OR periodByType.PRMK IS NOT NULL
|
||||||
|
THEN CAST(1 AS bit)
|
||||||
|
ELSE CAST(0 AS bit)
|
||||||
|
END AS HasTemplate,
|
||||||
|
typeTemplate.LastDocumentNumber AS LastDocumentNumber,
|
||||||
|
typeTemplate.LastAcceptedOn AS LastAcceptedOn,
|
||||||
|
CASE
|
||||||
|
WHEN typeTemplate.LastDocumentNumber IS NOT NULL THEN N'Шаблон по типоразмеру'
|
||||||
|
WHEN periodByType.PRMK IS NOT NULL THEN N'Период из TPRMCP'
|
||||||
|
ELSE N''
|
||||||
|
END AS TemplateSource
|
||||||
|
FROM dbo.TPRZ sizeInfo
|
||||||
|
LEFT JOIN dbo.TIPS tips ON tips.IDTIPS = sizeInfo.IDTIPS
|
||||||
|
LEFT JOIN dbo.SPNMTP names ON names.IDSPNMTP = tips.IDSPNMTP
|
||||||
|
LEFT JOIN dbo.SPOI areas ON areas.IDSPOI = tips.IDSPOI
|
||||||
|
OUTER APPLY
|
||||||
|
(
|
||||||
|
SELECT TOP (1)
|
||||||
|
history.NNZVPV AS LastDocumentNumber,
|
||||||
|
history.DTPRM AS LastAcceptedOn
|
||||||
|
FROM dbo.EKZMK history
|
||||||
|
JOIN dbo.EKZ instrumentOfSameType ON instrumentOfSameType.IDEKZ = history.IDEKZ
|
||||||
|
WHERE instrumentOfSameType.IDTPRZ = sizeInfo.IDTPRZ
|
||||||
|
ORDER BY ISNULL(history.DTPRM, CONVERT(datetime, '19000101', 112)) DESC, history.IDEKZMK DESC
|
||||||
|
) typeTemplate
|
||||||
|
OUTER APPLY
|
||||||
|
(
|
||||||
|
SELECT TOP (1)
|
||||||
|
t.PRMK
|
||||||
|
FROM dbo.TPRMCP t
|
||||||
|
WHERE t.IDTPRZ = sizeInfo.IDTPRZ
|
||||||
|
ORDER BY t.IDTPRMCP DESC
|
||||||
|
) periodByType
|
||||||
|
ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, sizeInfo.NNGSRS;";
|
||||||
|
|
||||||
|
var instrumentTypes = new List<AvailableInstrumentItem>();
|
||||||
|
|
||||||
|
using (var connection = CreateConnection())
|
||||||
|
using (var command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
connection.Open();
|
||||||
|
command.CommandTimeout = 60;
|
||||||
|
|
||||||
|
using (var reader = command.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
instrumentTypes.Add(new AvailableInstrumentItem
|
||||||
|
{
|
||||||
|
InstrumentId = GetInt32(reader, "InstrumentId"),
|
||||||
|
TypeSizeId = GetInt32(reader, "TypeSizeId"),
|
||||||
|
SerialNumber = GetString(reader, "SerialNumber"),
|
||||||
|
InventoryNumber = GetString(reader, "InventoryNumber"),
|
||||||
|
CustomerName = GetString(reader, "CustomerName"),
|
||||||
|
InstrumentType = GetString(reader, "InstrumentType"),
|
||||||
|
InstrumentName = GetString(reader, "InstrumentName"),
|
||||||
|
MeasurementArea = GetString(reader, "MeasurementArea"),
|
||||||
|
RegistryNumber = GetString(reader, "RegistryNumber"),
|
||||||
|
RangeText = GetString(reader, "RangeText"),
|
||||||
|
AccuracyText = GetString(reader, "AccuracyText"),
|
||||||
|
HasTemplate = GetBoolean(reader, "HasTemplate"),
|
||||||
|
LastDocumentNumber = GetString(reader, "LastDocumentNumber"),
|
||||||
|
LastAcceptedOn = GetNullableDateTime(reader, "LastAcceptedOn"),
|
||||||
|
TemplateSource = GetString(reader, "TemplateSource")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return instrumentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReadOnlyList<OpenDocumentConflictInfo> FindOpenDocumentConflicts(int customerId, string currentDocumentNumber, IEnumerable<PsvDocumentLine> candidateLines)
|
||||||
|
{
|
||||||
|
if (customerId <= 0 || candidateLines == null)
|
||||||
|
{
|
||||||
|
return new List<OpenDocumentConflictInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var connection = CreateConnection())
|
||||||
|
{
|
||||||
|
connection.Open();
|
||||||
|
return LoadOpenDocumentConflicts(connection, null, customerId, currentDocumentNumber, candidateLines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void ResetLineVerification(int cardId)
|
public void ResetLineVerification(int cardId)
|
||||||
{
|
{
|
||||||
if (cardId <= 0)
|
if (cardId <= 0)
|
||||||
@@ -576,9 +681,9 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, z.NNZV;";
|
|||||||
var distinctPendingLines = pendingLines == null
|
var distinctPendingLines = pendingLines == null
|
||||||
? new List<PsvDocumentLine>()
|
? new List<PsvDocumentLine>()
|
||||||
: pendingLines
|
: pendingLines
|
||||||
.Where(delegate(PsvDocumentLine line) { return line != null && line.InstrumentId > 0; })
|
.Where(IsPendingLineReadyForSave)
|
||||||
.GroupBy(delegate(PsvDocumentLine line) { return line.InstrumentId; })
|
.GroupBy(GetPendingLineSaveKey, StringComparer.OrdinalIgnoreCase)
|
||||||
.Select(delegate(IGrouping<int, PsvDocumentLine> group) { return group.First(); })
|
.Select(delegate(IGrouping<string, PsvDocumentLine> group) { return group.First(); })
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
using (var connection = CreateConnection())
|
using (var connection = CreateConnection())
|
||||||
@@ -592,6 +697,20 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, z.NNZV;";
|
|||||||
throw new InvalidOperationException(string.Format("ПСВ с номером \"{0}\" уже существует.", normalizedNumber));
|
throw new InvalidOperationException(string.Format("ПСВ с номером \"{0}\" уже существует.", normalizedNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (document.CustomerId.HasValue)
|
||||||
|
{
|
||||||
|
var openDocumentConflicts = LoadOpenDocumentConflicts(
|
||||||
|
connection,
|
||||||
|
transaction,
|
||||||
|
document.CustomerId.Value,
|
||||||
|
currentDocumentNumber,
|
||||||
|
distinctPendingLines);
|
||||||
|
if (openDocumentConflicts.Count > 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(BuildOpenDocumentConflictMessage(openDocumentConflicts));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var updatedEkzMkCount = 0;
|
var updatedEkzMkCount = 0;
|
||||||
if (!string.IsNullOrWhiteSpace(currentDocumentNumber))
|
if (!string.IsNullOrWhiteSpace(currentDocumentNumber))
|
||||||
{
|
{
|
||||||
@@ -611,9 +730,18 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, z.NNZV;";
|
|||||||
|
|
||||||
foreach (var pendingLine in distinctPendingLines)
|
foreach (var pendingLine in distinctPendingLines)
|
||||||
{
|
{
|
||||||
|
var duplicateKey = pendingLine.DuplicateKey;
|
||||||
|
if (string.IsNullOrWhiteSpace(duplicateKey))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Не удалось определить ключ дубликата для строки ПСВ.");
|
||||||
|
}
|
||||||
|
|
||||||
var instrumentId = pendingLine.InstrumentId;
|
var instrumentId = pendingLine.InstrumentId;
|
||||||
var instrumentIdentity = LoadInstrumentIdentity(connection, transaction, instrumentId);
|
var instrumentIdentity = new InstrumentIdentityInfo
|
||||||
if (instrumentIdentity == null)
|
{
|
||||||
|
DuplicateKey = duplicateKey
|
||||||
|
};
|
||||||
|
if (string.IsNullOrWhiteSpace(duplicateKey))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(string.Format("Прибор IDEKZ={0} не найден.", instrumentId));
|
throw new InvalidOperationException(string.Format("Прибор IDEKZ={0} не найден.", instrumentId));
|
||||||
}
|
}
|
||||||
@@ -624,6 +752,7 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, z.NNZV;";
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instrumentId = ResolveInstrumentIdForPendingLine(connection, transaction, document, pendingLine);
|
||||||
var template = LoadTemplate(connection, transaction, instrumentId);
|
var template = LoadTemplate(connection, transaction, instrumentId);
|
||||||
if (template == null)
|
if (template == null)
|
||||||
{
|
{
|
||||||
@@ -786,6 +915,62 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, z.NNZV;";
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetPendingLineSaveKey(PsvDocumentLine line)
|
||||||
|
{
|
||||||
|
if (line == null)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return line.InstrumentId > 0
|
||||||
|
? string.Format("ID:{0}", line.InstrumentId)
|
||||||
|
: string.Format("NEW:{0}", line.DuplicateKey ?? string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsPendingLineReadyForSave(PsvDocumentLine line)
|
||||||
|
{
|
||||||
|
return line != null
|
||||||
|
&& (line.InstrumentId > 0
|
||||||
|
|| (line.TypeSizeId > 0 && !string.IsNullOrWhiteSpace(line.SerialNumber)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ResolveInstrumentIdForPendingLine(SqlConnection connection, SqlTransaction transaction, DocumentEditorResult document, PsvDocumentLine pendingLine)
|
||||||
|
{
|
||||||
|
if (pendingLine == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Строка ПСВ для сохранения не задана.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pendingLine.InstrumentId > 0)
|
||||||
|
{
|
||||||
|
return pendingLine.InstrumentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pendingLine.TypeSizeId <= 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Для новой строки ПСВ не указан типоразмер прибора.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var serialNumber = string.IsNullOrWhiteSpace(pendingLine.SerialNumber) ? null : pendingLine.SerialNumber.Trim();
|
||||||
|
if (serialNumber == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Для новой строки ПСВ не указан заводской номер.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!document.CustomerId.HasValue)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Для добавления прибора по типу должен быть выбран заказчик ПСВ.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingInstrumentId = FindExistingInstrumentId(connection, transaction, pendingLine.TypeSizeId, document.CustomerId.Value, serialNumber);
|
||||||
|
if (existingInstrumentId.HasValue)
|
||||||
|
{
|
||||||
|
return existingInstrumentId.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return InsertInstrument(connection, transaction, pendingLine.TypeSizeId, document.CustomerId.Value, serialNumber);
|
||||||
|
}
|
||||||
|
|
||||||
private static List<int> NormalizeCardIds(IEnumerable<int> cardIds, string invalidCardMessage, string emptyListMessage)
|
private static List<int> NormalizeCardIds(IEnumerable<int> cardIds, string invalidCardMessage, string emptyListMessage)
|
||||||
{
|
{
|
||||||
if (cardIds == null)
|
if (cardIds == null)
|
||||||
@@ -807,6 +992,196 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, z.NNZV;";
|
|||||||
return normalizedCardIds;
|
return normalizedCardIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int? FindExistingInstrumentId(SqlConnection connection, SqlTransaction transaction, int typeSizeId, int customerId, string serialNumber)
|
||||||
|
{
|
||||||
|
const string sql = @"
|
||||||
|
SELECT TOP (1) z.IDEKZ
|
||||||
|
FROM dbo.EKZ z
|
||||||
|
WHERE z.IDTPRZ = @TypeSizeId
|
||||||
|
AND z.IDFRPDV = @CustomerId
|
||||||
|
AND z.NNZV = @SerialNumber
|
||||||
|
AND ISNULL(z.IsDeleted, 0) = 0
|
||||||
|
ORDER BY z.IDEKZ DESC;";
|
||||||
|
|
||||||
|
using (var command = new SqlCommand(sql, connection, transaction))
|
||||||
|
{
|
||||||
|
command.CommandTimeout = 60;
|
||||||
|
command.Parameters.Add("@TypeSizeId", SqlDbType.Int).Value = typeSizeId;
|
||||||
|
command.Parameters.Add("@CustomerId", SqlDbType.Int).Value = customerId;
|
||||||
|
command.Parameters.Add("@SerialNumber", SqlDbType.VarChar, 30).Value = serialNumber;
|
||||||
|
|
||||||
|
var result = command.ExecuteScalar();
|
||||||
|
return result == null || result == DBNull.Value ? (int?)null : Convert.ToInt32(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int InsertInstrument(SqlConnection connection, SqlTransaction transaction, int typeSizeId, int customerId, string serialNumber)
|
||||||
|
{
|
||||||
|
const string sql = @"
|
||||||
|
INSERT INTO dbo.EKZ
|
||||||
|
(
|
||||||
|
IDTPRZ,
|
||||||
|
IDFRPDV,
|
||||||
|
KLSIPR,
|
||||||
|
NNZV,
|
||||||
|
GUIDEKZ,
|
||||||
|
IsDeleted
|
||||||
|
)
|
||||||
|
VALUES
|
||||||
|
(
|
||||||
|
@TypeSizeId,
|
||||||
|
@CustomerId,
|
||||||
|
@Klsipr,
|
||||||
|
@SerialNumber,
|
||||||
|
@GuidEkz,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
SELECT CAST(SCOPE_IDENTITY() AS int);";
|
||||||
|
|
||||||
|
using (var command = new SqlCommand(sql, connection, transaction))
|
||||||
|
{
|
||||||
|
command.CommandTimeout = 60;
|
||||||
|
command.Parameters.Add("@TypeSizeId", SqlDbType.Int).Value = typeSizeId;
|
||||||
|
command.Parameters.Add("@CustomerId", SqlDbType.Int).Value = customerId;
|
||||||
|
command.Parameters.Add("@Klsipr", SqlDbType.Int).Value = 1;
|
||||||
|
command.Parameters.Add("@SerialNumber", SqlDbType.VarChar, 30).Value = serialNumber;
|
||||||
|
command.Parameters.Add("@GuidEkz", SqlDbType.UniqueIdentifier).Value = Guid.NewGuid();
|
||||||
|
return Convert.ToInt32(command.ExecuteScalar());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string BuildOpenDocumentConflictMessage(IEnumerable<OpenDocumentConflictInfo> conflicts)
|
||||||
|
{
|
||||||
|
var materializedConflicts = conflicts == null
|
||||||
|
? new List<OpenDocumentConflictInfo>()
|
||||||
|
: conflicts
|
||||||
|
.Where(delegate(OpenDocumentConflictInfo conflict) { return conflict != null; })
|
||||||
|
.GroupBy(delegate(OpenDocumentConflictInfo conflict)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
"{0}|{1}|{2}",
|
||||||
|
conflict.DocumentNumber ?? string.Empty,
|
||||||
|
conflict.TypeSizeId,
|
||||||
|
conflict.SerialNumber ?? string.Empty);
|
||||||
|
}, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.Select(delegate(IGrouping<string, OpenDocumentConflictInfo> group) { return group.First(); })
|
||||||
|
.OrderBy(delegate(OpenDocumentConflictInfo conflict) { return conflict.SerialNumber ?? string.Empty; })
|
||||||
|
.ThenBy(delegate(OpenDocumentConflictInfo conflict) { return conflict.DocumentNumber ?? string.Empty; })
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (materializedConflicts.Count == 0)
|
||||||
|
{
|
||||||
|
return "Прибор уже находится в другой открытой ПСВ этого заказчика.";
|
||||||
|
}
|
||||||
|
|
||||||
|
var preview = materializedConflicts
|
||||||
|
.Take(5)
|
||||||
|
.Select(delegate(OpenDocumentConflictInfo conflict)
|
||||||
|
{
|
||||||
|
return string.Format("зав. № {0} -> {1}", conflict.SerialNumber, conflict.DocumentNumber);
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var suffix = materializedConflicts.Count > preview.Count
|
||||||
|
? string.Format(" Еще конфликтов: {0}.", materializedConflicts.Count - preview.Count)
|
||||||
|
: string.Empty;
|
||||||
|
|
||||||
|
return string.Format(
|
||||||
|
"Приборы уже находятся в других открытых ПСВ этого заказчика: {0}.{1}",
|
||||||
|
string.Join("; ", preview.ToArray()),
|
||||||
|
suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<OpenDocumentConflictInfo> LoadOpenDocumentConflicts(
|
||||||
|
SqlConnection connection,
|
||||||
|
SqlTransaction transaction,
|
||||||
|
int customerId,
|
||||||
|
string currentDocumentNumber,
|
||||||
|
IEnumerable<PsvDocumentLine> candidateLines)
|
||||||
|
{
|
||||||
|
var normalizedCandidates = candidateLines == null
|
||||||
|
? new List<PsvDocumentLine>()
|
||||||
|
: candidateLines
|
||||||
|
.Where(delegate(PsvDocumentLine line)
|
||||||
|
{
|
||||||
|
return line != null
|
||||||
|
&& line.TypeSizeId > 0
|
||||||
|
&& !string.IsNullOrWhiteSpace(line.SerialNumber);
|
||||||
|
})
|
||||||
|
.GroupBy(delegate(PsvDocumentLine line) { return line.OpenDocumentConflictKey; }, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.Select(delegate(IGrouping<string, PsvDocumentLine> group) { return group.First(); })
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (customerId <= 0 || normalizedCandidates.Count == 0)
|
||||||
|
{
|
||||||
|
return new List<OpenDocumentConflictInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
const string sql = @"
|
||||||
|
WITH ActiveDocuments AS
|
||||||
|
(
|
||||||
|
SELECT m.NNZVPV
|
||||||
|
FROM dbo.EKZMK m
|
||||||
|
WHERE NULLIF(LTRIM(RTRIM(m.NNZVPV)), N'') IS NOT NULL
|
||||||
|
GROUP BY m.NNZVPV
|
||||||
|
HAVING MAX(m.DTVDM) IS NULL
|
||||||
|
)
|
||||||
|
SELECT DISTINCT
|
||||||
|
m.NNZVPV AS DocumentNumber,
|
||||||
|
z.IDTPRZ AS TypeSizeId,
|
||||||
|
LTRIM(RTRIM(z.NNZV)) AS SerialNumber
|
||||||
|
FROM ActiveDocuments activeDocuments
|
||||||
|
JOIN dbo.EKZMK m ON m.NNZVPV = activeDocuments.NNZVPV
|
||||||
|
JOIN dbo.EKZ z ON z.IDEKZ = m.IDEKZ
|
||||||
|
WHERE z.IDFRPDV = @CustomerId
|
||||||
|
AND z.IDTPRZ = @TypeSizeId
|
||||||
|
AND LTRIM(RTRIM(z.NNZV)) = @SerialNumber
|
||||||
|
AND (@CurrentDocumentNumber = N'' OR m.NNZVPV <> @CurrentDocumentNumber)
|
||||||
|
ORDER BY m.NNZVPV;";
|
||||||
|
|
||||||
|
var conflicts = new List<OpenDocumentConflictInfo>();
|
||||||
|
|
||||||
|
foreach (var candidateLine in normalizedCandidates)
|
||||||
|
{
|
||||||
|
using (var command = new SqlCommand(sql, connection, transaction))
|
||||||
|
{
|
||||||
|
command.CommandTimeout = 60;
|
||||||
|
command.Parameters.Add("@CustomerId", SqlDbType.Int).Value = customerId;
|
||||||
|
command.Parameters.Add("@TypeSizeId", SqlDbType.Int).Value = candidateLine.TypeSizeId;
|
||||||
|
command.Parameters.Add("@SerialNumber", SqlDbType.VarChar, 30).Value = candidateLine.SerialNumber.Trim();
|
||||||
|
command.Parameters.Add("@CurrentDocumentNumber", SqlDbType.NVarChar, 60).Value = currentDocumentNumber ?? string.Empty;
|
||||||
|
|
||||||
|
using (var reader = command.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
conflicts.Add(new OpenDocumentConflictInfo
|
||||||
|
{
|
||||||
|
DocumentNumber = GetString(reader, "DocumentNumber"),
|
||||||
|
TypeSizeId = GetInt32(reader, "TypeSizeId"),
|
||||||
|
SerialNumber = GetString(reader, "SerialNumber")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return conflicts
|
||||||
|
.GroupBy(delegate(OpenDocumentConflictInfo conflict)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
"{0}|{1}|{2}",
|
||||||
|
conflict.DocumentNumber ?? string.Empty,
|
||||||
|
conflict.TypeSizeId,
|
||||||
|
conflict.SerialNumber ?? string.Empty);
|
||||||
|
}, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.Select(delegate(IGrouping<string, OpenDocumentConflictInfo> group) { return group.First(); })
|
||||||
|
.OrderBy(delegate(OpenDocumentConflictInfo conflict) { return conflict.SerialNumber ?? string.Empty; })
|
||||||
|
.ThenBy(delegate(OpenDocumentConflictInfo conflict) { return conflict.DocumentNumber ?? string.Empty; })
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
private static SqlConnection CreateConnection()
|
private static SqlConnection CreateConnection()
|
||||||
{
|
{
|
||||||
var connectionString = ConfigurationManager.ConnectionStrings["AsumsSql"];
|
var connectionString = ConfigurationManager.ConnectionStrings["AsumsSql"];
|
||||||
@@ -1179,6 +1554,7 @@ VALUES
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
@NNZVPV,
|
@NNZVPV,
|
||||||
|
NULL,
|
||||||
@NNNKL,
|
@NNNKL,
|
||||||
@PRMK,
|
@PRMK,
|
||||||
@DTMKFK,
|
@DTMKFK,
|
||||||
|
|||||||
@@ -133,6 +133,8 @@ namespace XLAB
|
|||||||
|
|
||||||
public int InstrumentId { get; set; }
|
public int InstrumentId { get; set; }
|
||||||
|
|
||||||
|
public int TypeSizeId { get; set; }
|
||||||
|
|
||||||
public string SerialNumber { get; set; }
|
public string SerialNumber { get; set; }
|
||||||
|
|
||||||
public string InventoryNumber { get; set; }
|
public string InventoryNumber { get; set; }
|
||||||
@@ -197,6 +199,14 @@ namespace XLAB
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string OpenDocumentConflictKey
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return BuildOpenDocumentConflictKey(TypeSizeId, SerialNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string ResultText
|
public string ResultText
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -237,6 +247,11 @@ namespace XLAB
|
|||||||
NormalizeKeyPart(serialNumber));
|
NormalizeKeyPart(serialNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string BuildOpenDocumentConflictKey(int typeSizeId, string serialNumber)
|
||||||
|
{
|
||||||
|
return string.Format("{0}|{1}", typeSizeId, NormalizeKeyPart(serialNumber));
|
||||||
|
}
|
||||||
|
|
||||||
private static string NormalizeKeyPart(string value)
|
private static string NormalizeKeyPart(string value)
|
||||||
{
|
{
|
||||||
return string.IsNullOrWhiteSpace(value) ? string.Empty : value.Trim().ToUpperInvariant();
|
return string.IsNullOrWhiteSpace(value) ? string.Empty : value.Trim().ToUpperInvariant();
|
||||||
@@ -352,6 +367,15 @@ namespace XLAB
|
|||||||
public DateTime AcceptedOn { get; set; }
|
public DateTime AcceptedOn { get; set; }
|
||||||
|
|
||||||
public DateTime? IssuedOn { get; set; }
|
public DateTime? IssuedOn { get; set; }
|
||||||
|
|
||||||
|
public int? CustomerId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class InstrumentTypeSelectionResult
|
||||||
|
{
|
||||||
|
public AvailableInstrumentItem TypeItem { get; set; }
|
||||||
|
|
||||||
|
public string SerialNumber { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class VerificationEditSeed
|
public sealed class VerificationEditSeed
|
||||||
@@ -392,6 +416,23 @@ namespace XLAB
|
|||||||
public string VerifierName { get; set; }
|
public string VerifierName { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal sealed class OpenDocumentConflictInfo
|
||||||
|
{
|
||||||
|
public string DocumentNumber { get; set; }
|
||||||
|
|
||||||
|
public int TypeSizeId { get; set; }
|
||||||
|
|
||||||
|
public string SerialNumber { get; set; }
|
||||||
|
|
||||||
|
public string OpenDocumentConflictKey
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return PsvDocumentLine.BuildOpenDocumentConflictKey(TypeSizeId, SerialNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal sealed class DocumentDeleteResult
|
internal sealed class DocumentDeleteResult
|
||||||
{
|
{
|
||||||
public int DeletedEkzMkFctvlCount { get; set; }
|
public int DeletedEkzMkFctvlCount { get; set; }
|
||||||
|
|||||||
93
XLAB/SelectInstrumentTypeWindow.xaml
Normal file
93
XLAB/SelectInstrumentTypeWindow.xaml
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
<Window x:Class="XLAB.SelectInstrumentTypeWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Добавить по типу"
|
||||||
|
Height="720"
|
||||||
|
Width="1120"
|
||||||
|
MinHeight="520"
|
||||||
|
MinWidth="900"
|
||||||
|
WindowStartupLocation="CenterOwner">
|
||||||
|
<Grid Margin="12">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<TextBlock FontWeight="SemiBold"
|
||||||
|
Text="{Binding CustomerName, StringFormat=Заказчик: {0}}" />
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="1"
|
||||||
|
Margin="0,8,0,8"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock Width="150"
|
||||||
|
Margin="0,0,8,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="Поиск" />
|
||||||
|
<TextBox Width="320"
|
||||||
|
Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<DataGrid Grid.Row="2"
|
||||||
|
ItemsSource="{Binding InstrumentTypesView}"
|
||||||
|
SelectedItem="{Binding SelectedType, Mode=TwoWay}"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
CanUserAddRows="False"
|
||||||
|
IsReadOnly="True"
|
||||||
|
HeadersVisibility="Column">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Header="Номер госреестра"
|
||||||
|
Width="120"
|
||||||
|
Binding="{Binding RegistryNumber}" />
|
||||||
|
<DataGridTextColumn Header="Наименование"
|
||||||
|
Width="240"
|
||||||
|
Binding="{Binding InstrumentName}" />
|
||||||
|
<DataGridTextColumn Header="Тип"
|
||||||
|
Width="150"
|
||||||
|
Binding="{Binding InstrumentType}" />
|
||||||
|
<DataGridTextColumn Header="Диапазон"
|
||||||
|
Width="180"
|
||||||
|
Binding="{Binding RangeText}" />
|
||||||
|
<DataGridTextColumn Header="Характеристики"
|
||||||
|
Width="160"
|
||||||
|
Binding="{Binding AccuracyText}" />
|
||||||
|
<DataGridTextColumn Header="Область"
|
||||||
|
Width="*"
|
||||||
|
Binding="{Binding MeasurementArea}" />
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="3"
|
||||||
|
Margin="0,10,0,0"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock Width="150"
|
||||||
|
Margin="0,0,8,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="Заводской номер" />
|
||||||
|
<TextBox Width="320"
|
||||||
|
Text="{Binding SerialNumber, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="4"
|
||||||
|
Margin="0,8,0,0"
|
||||||
|
Foreground="DimGray"
|
||||||
|
Text="{Binding StatusText}" />
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="5"
|
||||||
|
Margin="0,12,0,0"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
HorizontalAlignment="Right">
|
||||||
|
<Button Width="90"
|
||||||
|
Margin="0,0,8,0"
|
||||||
|
IsDefault="True"
|
||||||
|
Command="{Binding ConfirmCommand}"
|
||||||
|
Content="Сохранить" />
|
||||||
|
<Button Width="90"
|
||||||
|
Command="{Binding CancelCommand}"
|
||||||
|
Content="Отмена" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
20
XLAB/SelectInstrumentTypeWindow.xaml.cs
Normal file
20
XLAB/SelectInstrumentTypeWindow.xaml.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace XLAB
|
||||||
|
{
|
||||||
|
public partial class SelectInstrumentTypeWindow : Window
|
||||||
|
{
|
||||||
|
internal SelectInstrumentTypeWindow(SelectInstrumentTypeWindowViewModel viewModel)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
DataContext = viewModel;
|
||||||
|
viewModel.CloseRequested += ViewModelOnCloseRequested;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ViewModelOnCloseRequested(object sender, bool? dialogResult)
|
||||||
|
{
|
||||||
|
DialogResult = dialogResult;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
161
XLAB/SelectInstrumentTypeWindowViewModel.cs
Normal file
161
XLAB/SelectInstrumentTypeWindowViewModel.cs
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace XLAB
|
||||||
|
{
|
||||||
|
internal sealed class SelectInstrumentTypeWindowViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
private string _searchText;
|
||||||
|
private AvailableInstrumentItem _selectedType;
|
||||||
|
private string _serialNumber;
|
||||||
|
private string _statusText;
|
||||||
|
|
||||||
|
public SelectInstrumentTypeWindowViewModel(string customerName, IReadOnlyList<AvailableInstrumentItem> instrumentTypes)
|
||||||
|
{
|
||||||
|
CustomerName = customerName ?? string.Empty;
|
||||||
|
InstrumentTypes = new ObservableCollection<AvailableInstrumentItem>(instrumentTypes ?? new List<AvailableInstrumentItem>());
|
||||||
|
InstrumentTypesView = CollectionViewSource.GetDefaultView(InstrumentTypes);
|
||||||
|
InstrumentTypesView.Filter = FilterTypes;
|
||||||
|
|
||||||
|
ConfirmCommand = new RelayCommand(Confirm, CanConfirm);
|
||||||
|
CancelCommand = new RelayCommand(Cancel);
|
||||||
|
UpdateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<bool?> CloseRequested;
|
||||||
|
|
||||||
|
public ICommand CancelCommand { get; private set; }
|
||||||
|
|
||||||
|
public ICommand ConfirmCommand { get; private set; }
|
||||||
|
|
||||||
|
public string CustomerName { get; private set; }
|
||||||
|
|
||||||
|
public ObservableCollection<AvailableInstrumentItem> InstrumentTypes { get; private set; }
|
||||||
|
|
||||||
|
public ICollectionView InstrumentTypesView { get; private set; }
|
||||||
|
|
||||||
|
public string SearchText
|
||||||
|
{
|
||||||
|
get { return _searchText; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref _searchText, value))
|
||||||
|
{
|
||||||
|
InstrumentTypesView.Refresh();
|
||||||
|
UpdateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AvailableInstrumentItem SelectedType
|
||||||
|
{
|
||||||
|
get { return _selectedType; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref _selectedType, value))
|
||||||
|
{
|
||||||
|
((RelayCommand)ConfirmCommand).RaiseCanExecuteChanged();
|
||||||
|
UpdateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SerialNumber
|
||||||
|
{
|
||||||
|
get { return _serialNumber; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref _serialNumber, value))
|
||||||
|
{
|
||||||
|
((RelayCommand)ConfirmCommand).RaiseCanExecuteChanged();
|
||||||
|
UpdateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string StatusText
|
||||||
|
{
|
||||||
|
get { return _statusText; }
|
||||||
|
private set { SetProperty(ref _statusText, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstrumentTypeSelectionResult GetResult()
|
||||||
|
{
|
||||||
|
return SelectedType == null
|
||||||
|
? null
|
||||||
|
: new InstrumentTypeSelectionResult
|
||||||
|
{
|
||||||
|
TypeItem = SelectedType,
|
||||||
|
SerialNumber = string.IsNullOrWhiteSpace(SerialNumber) ? string.Empty : SerialNumber.Trim()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Cancel(object parameter)
|
||||||
|
{
|
||||||
|
RaiseCloseRequested(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CanConfirm(object parameter)
|
||||||
|
{
|
||||||
|
return SelectedType != null
|
||||||
|
&& !string.IsNullOrWhiteSpace(SerialNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Confirm(object parameter)
|
||||||
|
{
|
||||||
|
RaiseCloseRequested(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool FilterTypes(object item)
|
||||||
|
{
|
||||||
|
var instrumentType = item as AvailableInstrumentItem;
|
||||||
|
if (instrumentType == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(SearchText))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Contains(instrumentType.RegistryNumber, SearchText)
|
||||||
|
|| Contains(instrumentType.InstrumentName, SearchText)
|
||||||
|
|| Contains(instrumentType.InstrumentType, SearchText)
|
||||||
|
|| Contains(instrumentType.RangeText, SearchText)
|
||||||
|
|| Contains(instrumentType.AccuracyText, SearchText)
|
||||||
|
|| Contains(instrumentType.MeasurementArea, SearchText);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool Contains(string source, string searchText)
|
||||||
|
{
|
||||||
|
return !string.IsNullOrWhiteSpace(source)
|
||||||
|
&& source.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RaiseCloseRequested(bool? dialogResult)
|
||||||
|
{
|
||||||
|
var handler = CloseRequested;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler(this, dialogResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateStatus()
|
||||||
|
{
|
||||||
|
var visibleCount = InstrumentTypesView.Cast<object>().Count();
|
||||||
|
StatusText = string.Format(
|
||||||
|
"Всего типов: {0}. По фильтру: {1}. Выбран тип: {2}. Заводской номер: {3}.",
|
||||||
|
InstrumentTypes.Count,
|
||||||
|
visibleCount,
|
||||||
|
SelectedType == null ? "нет" : "да",
|
||||||
|
string.IsNullOrWhiteSpace(SerialNumber) ? "не указан" : "указан");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -90,6 +90,15 @@
|
|||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="SelectInstrumentsWindowViewModel.cs" />
|
<Compile Include="SelectInstrumentsWindowViewModel.cs" />
|
||||||
|
<Page Include="SelectInstrumentTypeWindow.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Compile Include="SelectInstrumentTypeWindow.xaml.cs">
|
||||||
|
<DependentUpon>SelectInstrumentTypeWindow.xaml</DependentUpon>
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="SelectInstrumentTypeWindowViewModel.cs" />
|
||||||
<Page Include="VerificationEditWindow.xaml">
|
<Page Include="VerificationEditWindow.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
|||||||
Reference in New Issue
Block a user