Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Limit Preis als Attribut #1330

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -17,6 +17,8 @@ public final class Colors
public static final Color DARK_RED = Display.getDefault().getSystemColor(SWT.COLOR_DARK_RED);
public static final Color DARK_GREEN = Display.getDefault().getSystemColor(SWT.COLOR_DARK_GREEN);
public static final Color BLACK = Display.getDefault().getSystemColor(SWT.COLOR_BLACK);
public static final Color RED = Display.getDefault().getSystemColor(SWT.COLOR_RED);
public static final Color GREEN = Display.getDefault().getSystemColor(SWT.COLOR_GREEN);

private static final ColorRegistry REGISTRY = new ColorRegistry();

Expand Down
Expand Up @@ -10,15 +10,20 @@

import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;

import name.abuchen.portfolio.model.Adaptor;
import name.abuchen.portfolio.model.Attributable;
import name.abuchen.portfolio.model.AttributeType;
import name.abuchen.portfolio.model.Attributes;
import name.abuchen.portfolio.model.Client;
import name.abuchen.portfolio.model.LimitPrice;
import name.abuchen.portfolio.model.Security;
import name.abuchen.portfolio.model.SecurityPrice;
import name.abuchen.portfolio.ui.Images;
import name.abuchen.portfolio.ui.Messages;
import name.abuchen.portfolio.ui.util.Colors;
import name.abuchen.portfolio.ui.util.viewers.AttributeEditingSupport;
import name.abuchen.portfolio.ui.util.viewers.BooleanAttributeEditingSupport;
import name.abuchen.portfolio.ui.util.viewers.Column;
Expand Down Expand Up @@ -110,6 +115,62 @@ private Optional<Boolean> getValue(Object element)
return Optional.ofNullable((Boolean) attributes.get(attribute));
}
}

private static final class LimitPriceLabelProvider extends ColumnLabelProvider
{
private final AttributeType attribute;

private LimitPriceLabelProvider(AttributeType attribute)
{
this.attribute = attribute;
}

@Override
public String getText(Object element)
{
Security security = Adaptor.adapt(Security.class, element);
if (security == null)
return null;

Attributes attributes = security.getAttributes();
if (attributes == null)
return null;

Object value = attributes.get(attribute);
return attribute.getConverter().toString(value);
}

@Override
public Color getBackground(Object element)
{
Security security = Adaptor.adapt(Security.class, element);
if(security == null)
return null;

Attributes attributes = security.getAttributes();
LimitPrice limit = (LimitPrice) attributes.get(attribute);
if(limit == null)
return null;

SecurityPrice latestSecurityPrice = security.getSecurityPrice(LocalDate.now());
if(latestSecurityPrice == null)
return null;

switch(limit.getCompareType())
{
case GREATER_OR_EQUAL:
return (latestSecurityPrice.getValue() >= limit.getValue() ? Colors.GREEN : null);
case SMALLER_OR_EQUAL:
return (latestSecurityPrice.getValue() >= limit.getValue() ? Colors.RED : null);
case GREATER:
return (latestSecurityPrice.getValue() >= limit.getValue() ? Colors.GREEN : null);
case SMALLER:
return (latestSecurityPrice.getValue() >= limit.getValue() ? Colors.RED : null);
default:
return null;
}
}
}

private static final String ID = "attribute$"; //$NON-NLS-1$

Expand All @@ -127,6 +188,11 @@ private AttributeColumn(final AttributeType attribute)
setLabelProvider(new BooleanLabelProvider(attribute));
new BooleanAttributeEditingSupport(attribute).attachTo(this);
}
else if (attribute.getType() == LimitPrice.class)
{
setLabelProvider(new LimitPriceLabelProvider(attribute));
new AttributeEditingSupport(attribute).attachTo(this);
}
else
{
setLabelProvider(new AttributeLabelProvider(attribute));
Expand Down
Expand Up @@ -4,6 +4,7 @@
import java.util.ResourceBundle;

import name.abuchen.portfolio.model.AttributeType;
import name.abuchen.portfolio.model.LimitPrice;
import name.abuchen.portfolio.model.AttributeType.AmountConverter;
import name.abuchen.portfolio.model.AttributeType.AmountPlainConverter;
import name.abuchen.portfolio.model.AttributeType.BooleanConverter;
Expand All @@ -14,6 +15,7 @@
import name.abuchen.portfolio.model.AttributeType.QuoteConverter;
import name.abuchen.portfolio.model.AttributeType.ShareConverter;
import name.abuchen.portfolio.model.AttributeType.StringConverter;
import name.abuchen.portfolio.model.AttributeType.LimitPriceConverter;

public enum AttributeFieldType
{
Expand All @@ -25,7 +27,8 @@ public enum AttributeFieldType
QUOTE(Long.class, QuoteConverter.class), //
SHARE(Long.class, ShareConverter.class), //
DATE(LocalDate.class, DateConverter.class), //
BOOLEAN(Boolean.class, BooleanConverter.class);
BOOLEAN(Boolean.class, BooleanConverter.class), //
LIMIT_PRICE(LimitPrice.class, LimitPriceConverter.class);
buchen marked this conversation as resolved.
Show resolved Hide resolved

private static final ResourceBundle RESOURCES = ResourceBundle
.getBundle("name.abuchen.portfolio.ui.views.settings.labels"); //$NON-NLS-1$
Expand Down
Expand Up @@ -16,3 +16,5 @@ QUOTE.name = Quote
SHARE.name = Share

STRING.name = Text

LIMIT_PRICE.name = Limit Price
Expand Up @@ -16,3 +16,5 @@ QUOTE.name = Kurs
SHARE.name = Anteil

STRING.name = Text

LIMIT_PRICE.name = Limit Preis
Expand Up @@ -217,6 +217,7 @@ public class Messages extends NLS
public static String MsgNoQuotesFoundInHTML;
public static String MsgNoResults;
public static String MsgNotANumber;
public static String MsgNotAComparator;
public static String MsgNotAPortflioFile;
public static String MsgPasswordMissing;
public static String MsgReadingFile;
Expand Down
Expand Up @@ -423,6 +423,8 @@ MsgNoResults = No results for '%s'

MsgNotANumber = Not a number: {0}

MsgNotAComparator = No valid comparator > >= < or <= found

MsgNotAPortflioFile = Invalid file format: not a Portfolio Performance file

MsgPasswordMissing = Password is missing
Expand Down
Expand Up @@ -415,6 +415,8 @@ MsgNoQuotesFoundInHTML = Keine Kurse gefunden: {0}\n\n{1}

MsgNoResults = Keine Ergebnisse f\u00FCr '%s'

MsgNotAComparator = Kein g�ltiger Verlgeich > >= < oder <= gefunden

MsgNotANumber = Eingabe ist keine g\u00FCltige Zahl: {0}

MsgNotAPortflioFile = Falsches Format: Datei ist keine Portfolio Performance Datei
Expand Down
Expand Up @@ -15,11 +15,13 @@
import java.util.regex.Pattern;

import name.abuchen.portfolio.Messages;
import name.abuchen.portfolio.model.LimitPrice.CompareType;
import name.abuchen.portfolio.money.Values;

public class AttributeType
{
private static final Pattern PATTERN = Pattern.compile("^([\\d.,-]*)$"); //$NON-NLS-1$
private static final Pattern LIMIT_PRICE_PATTERN = Pattern.compile("^\\s*(<=?|>=?)\\s*([0-9,.']+)$"); //$NON-NLS-1$

public interface Converter
{
Expand All @@ -44,6 +46,46 @@ public Object fromString(String value)
}

}

public static class LimitPriceConverter implements Converter
{
private final DecimalFormat full;

public LimitPriceConverter()
{
this.full = new DecimalFormat("#,###"); //$NON-NLS-1$
this.full.setParseBigDecimal(true);
}

@Override
public String toString(Object object)
{
return object != null ? ((LimitPrice) object).toString() : ""; //$NON-NLS-1$
}

@Override
public Object fromString(String value)
{
try
{
if(value.length() == 0)
return null;

Matcher m = LIMIT_PRICE_PATTERN.matcher(value);
if(!m.matches())
throw new IllegalArgumentException(Messages.MsgNotAComparator);

String compare = m.group(1);
long price = ((BigDecimal) full.parse(m.group(2))).multiply(Values.Quote.getBigDecimalFactor()).longValue();

return new LimitPrice(CompareType.valueOf(compare), price);
}
catch (ParseException e)
{
throw new IllegalArgumentException(e);
}
}
}

private static class LongConverter implements Converter
{
Expand Down
Expand Up @@ -24,7 +24,7 @@ public class Client
{
/* package */static final int MAJOR_VERSION = 1;

public static final int CURRENT_VERSION = 43;
public static final int CURRENT_VERSION = 44;
public static final int VERSION_WITH_CURRENCY_SUPPORT = 29;

private transient PropertyChangeSupport propertyChangeSupport; // NOSONAR
Expand Down
Expand Up @@ -574,7 +574,9 @@ private static void upgradeModel(Client client)
// added tax units to interest transaction
case 42:
// added data map to classification and assignemnt

case 43:
// added LimitPrice as attribute type

client.setVersion(Client.CURRENT_VERSION);
break;
case Client.CURRENT_VERSION:
Expand Down Expand Up @@ -1097,6 +1099,8 @@ private static synchronized XStream xstream()
xstream.useAttributeFor(SecurityPrice.class, "value");
xstream.aliasField("v", SecurityPrice.class, "value");

xstream.alias("limitPrice", LimitPrice.class);

xstream.alias("cpi", ConsumerPriceIndex.class);
xstream.useAttributeFor(ConsumerPriceIndex.class, "year");
xstream.aliasField("y", ConsumerPriceIndex.class, "year");
Expand Down
@@ -0,0 +1,82 @@
package name.abuchen.portfolio.model;

import java.util.Objects;

import name.abuchen.portfolio.money.Values;

public class LimitPrice implements Comparable<LimitPrice>
{
public enum CompareType
{
GREATER_OR_EQUAL(">="), //$NON-NLS-1$
SMALLER_OR_EQUAL("<="), //$NON-NLS-1$
GREATER(">"), //$NON-NLS-1$
SMALLER("<"); //$NON-NLS-1$

private String str;

CompareType(String compareString) {
this.str = compareString;
}

public String getCompareString() {
return str;
}
}

private CompareType compareType = null;
private long value;

public LimitPrice(CompareType type, long value)
{
this.compareType = type;
this.value = value;
}

public CompareType getCompareType()
{
return compareType;
}

public long getValue()
{
return value;
}

@Override
public int hashCode()
{
return Objects.hash(compareType, value);
}

@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;

LimitPrice other = (LimitPrice) obj;
if (value != other.value)
return false;
return Objects.equals(compareType.getCompareString(), other.compareType.getCompareString());
}

@Override
public int compareTo(LimitPrice other)
{
int compare = compareType.getCompareString().compareTo(other.getCompareType().getCompareString());
if (compare != 0)
return compare;
return (int) (value - other.getValue());
}

@Override
public String toString()
{
return (compareType != null ? compareType.getCompareString() + Values.Quote.format(value) : ""); //$NON-NLS-1$
}
}