Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de80724e1d | ||
|
|
c1a3d596c9 | ||
|
|
26070ec171 | ||
|
|
cd3ca09c9f |
No files matched your search
@@ -37,6 +37,7 @@ namespace bts.shell.manual_fills {
|
||||
|
||||
public ManualFillRow(ManualFillData data) {
|
||||
_data = data;
|
||||
persisted_data = data;
|
||||
key = data.key;
|
||||
_security = data.value.security;
|
||||
_account = data.value.account;
|
||||
@@ -93,6 +94,8 @@ namespace bts.shell.manual_fills {
|
||||
public ManualFillData data => _data ??
|
||||
(_data = new ManualFillData(key, new ManualFillTuple(new ManualFillImmutable(to_man_fill()), security, account, user))).Value;
|
||||
|
||||
public ManualFillData? persisted_data { get; }
|
||||
|
||||
public void revert() =>
|
||||
_committed_snapshot.Dispose();
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
VerticalAlignment="Stretch"
|
||||
CloseOnCancel="True"
|
||||
CloseOnOK="True"
|
||||
Header="{Binding security}"
|
||||
Header="{Binding security, Converter={StaticResource EditableSecurityTextConverter}}"
|
||||
IsEditMode="False"
|
||||
IsLazy="True"
|
||||
SecurityMap="{DynamicResource ResourceKey={x:Static u:ResourceKeys.Securities}}"
|
||||
|
||||
@@ -95,9 +95,13 @@ namespace bts.shell.manual_fills {
|
||||
if (selection_mon.filtered_items.Count < _max_unconfirmed_removes || BTSMessageBox.Confirm($"Are you sure you want to delete {selection_mon.filtered_items.Count} fills?", "Delete Fills")) {
|
||||
var persisted_fills = new List<ManualFill>();
|
||||
foreach (var r in selection_mon.filtered_items.ToList()) {
|
||||
if (r.placeholder_key.HasValue)
|
||||
if (r.placeholder_key.HasValue) {
|
||||
_placeholder_rows.RemoveSorted(r, _row_key_comparer);
|
||||
else persisted_fills.Add(r.to_man_fill());
|
||||
} else if (r.persisted_data.HasValue) {
|
||||
// this should always be true if placeholder_key doesn't have a value,
|
||||
// but it's [almost always] good practice to verify that a nullable has a value before accessing it.
|
||||
persisted_fills.Add(r.persisted_data.Value.value.manual_fill.CloneToMutable());
|
||||
}
|
||||
}
|
||||
await _model.delete_fills(persisted_fills);
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
<DataGridTemplateColumn c:DataGridEx.CellKey="{x:Static Security, MemberType={u:Nested usp:ManualFillsView.Columns}}" Header="Security" SortMemberPath="security">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding security}" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding security, Converter={StaticResource EditableSecurityTextConverter}}" VerticalAlignment="Center"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<DataGridTemplateColumn.CellEditingTemplate>
|
||||
@@ -139,7 +139,7 @@
|
||||
VerticalAlignment="Stretch"
|
||||
CloseOnCancel="True"
|
||||
CloseOnOK="True"
|
||||
Header="{Binding security}"
|
||||
Header="{Binding security, Converter={StaticResource EditableSecurityTextConverter}}"
|
||||
IsEditMode="False"
|
||||
IsLazy="True"
|
||||
SecurityMap="{Binding DataContext.security_map, RelativeSource={RelativeSource AncestorType=DataGrid}, Mode=OneWay}"
|
||||
|
||||
@@ -380,29 +380,17 @@ namespace mbts.spark {
|
||||
_error.handle_error(result, template, r => r.ErrorCode, e => e == OrderError.Ok, r => new uint?(r.OrderKey));
|
||||
|
||||
#region Manual Fillls
|
||||
public async Task<bool> create_manual_fills(IEnumerable<ManualFill> fills) {
|
||||
return await create_manual_fills(_create_fill_batch(fills));
|
||||
}
|
||||
public async Task<bool> create_manual_fills(ManualFillBatchImmutable fills) {
|
||||
var result = await _position_service.create_manual_fill_async(fills);
|
||||
return _handle_error(result);
|
||||
}
|
||||
public async Task<bool> create_manual_fills(IEnumerable<ManualFill> fills) =>
|
||||
(await _execute_manual_fill_op(fills, _position_service.create_manual_fill_async, "create manual fills"))
|
||||
.success;
|
||||
|
||||
public async Task<bool> update_manual_fills(IEnumerable<ManualFill> fills) {
|
||||
return await update_manual_fills(_create_fill_batch(fills));
|
||||
}
|
||||
public async Task<bool> update_manual_fills(ManualFillBatchImmutable fills) {
|
||||
var result = await _position_service.update_manual_fill_async(fills);
|
||||
return _handle_error(result);
|
||||
}
|
||||
public async Task<bool> update_manual_fills(IEnumerable<ManualFill> fills) =>
|
||||
(await _execute_manual_fill_op(fills, _position_service.update_manual_fill_async, "update manual fills"))
|
||||
.success;
|
||||
|
||||
public async Task<bool> delete_manual_fills(IEnumerable<ManualFill> fills) {
|
||||
return await delete_manual_fills(_create_fill_batch(fills));
|
||||
}
|
||||
public async Task<bool> delete_manual_fills(ManualFillBatchImmutable fills) {
|
||||
var result = await _position_service.remove_manual_fill_async(fills);
|
||||
return _handle_error(result);
|
||||
}
|
||||
public async Task<bool> delete_manual_fills(IEnumerable<ManualFill> fills) =>
|
||||
(await _execute_manual_fill_op(fills, _position_service.remove_manual_fill_async, "delete manual fills"))
|
||||
.success;
|
||||
|
||||
ManualFillBatchImmutable _create_fill_batch(IEnumerable<ManualFill> fills) {
|
||||
var batch = new ManualFillBatch();
|
||||
@@ -415,6 +403,17 @@ namespace mbts.spark {
|
||||
_error.report_error(result.error_message);
|
||||
return result.value.Response.All(r => r.Ok);
|
||||
}
|
||||
|
||||
Task<(PositionServiceResponse value, bool success)> _execute_manual_fill_op(
|
||||
IEnumerable<ManualFill> fills,
|
||||
Func<ManualFillBatchImmutable, Task<Result<PositionServiceResponse>>> execute_async,
|
||||
string desc) =>
|
||||
//
|
||||
_error.safe_execute(
|
||||
() => execute_async(_create_fill_batch(fills)),
|
||||
r => r.Response.All(op => op.Ok),
|
||||
r => string.Join("\n", r.Response.Where(op => op.Ok).Select(op => op.Msg)),
|
||||
desc);
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace mbts.ui.converters {
|
||||
class StaticValueConverterWrapper : IValueConverter {
|
||||
public object Value { get; set; }
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||
Value;
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using bts.collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace mbts.ui.converters {
|
||||
[ContentProperty(nameof(Map))]
|
||||
class ConverterMap : IValueConverter {
|
||||
readonly KeyedCollection<KeyConverter, object> _map = new KeyedCollection<KeyConverter, object>(kv => kv.Key);
|
||||
|
||||
public IList Map => _map;
|
||||
public IValueConverter Default { get; set; }
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
|
||||
if (_map.TryGetValue(value ?? KeyConverter.NullPlaceholder, out var kc)) {
|
||||
return kc.Converter.Convert(value, targetType, parameter, culture);
|
||||
} else if (Default != null) {
|
||||
return Default.Convert(value, targetType, parameter, culture);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
[ContentProperty(nameof(Converter))]
|
||||
class KeyConverter {
|
||||
object _key;
|
||||
// dictionaries/lookup classes typically prohibit null keys
|
||||
public static object NullPlaceholder => new _NullPlaceholder();
|
||||
public object Key { get => _key ?? NullPlaceholder; set => _key = value; }
|
||||
public IValueConverter Converter { get; set; }
|
||||
|
||||
struct _NullPlaceholder {
|
||||
public override bool Equals(object obj) => obj is _NullPlaceholder;
|
||||
public override int GetHashCode() => -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,11 @@
|
||||
<cv:CellPathConverter x:Key="CellPathConverter" />
|
||||
<cv:CellKeyConverter x:Key="CellKeyConverter" />
|
||||
<cv:SecurityDisplayTextConverter x:Key="SecurityTextConverter"/>
|
||||
<cv:ConverterMap x:Key="EditableSecurityTextConverter" Default="{x:Static cv:ValueConverters.SimpleString}">
|
||||
<cv:KeyConverter Key="{x:Null}">
|
||||
<cv:StaticValueConverterWrapper Value="(None)"/>
|
||||
</cv:KeyConverter>
|
||||
</cv:ConverterMap>
|
||||
<cv:NumericSignBrushConverter x:Key="NumericSignBrushConverter" />
|
||||
<cv:TickDisplayTextConverter x:Key="TickTextConverter" />
|
||||
<cv:DoubleTextConverter x:Key="DoubleTextConverter" />
|
||||
|
||||
Reference in new issue
Block a user