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

Allow to select an existing security to replace a newly imported one #3494

Merged
merged 3 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,7 @@ public class Messages extends NLS
public static String LabelSecurityTransfer;
public static String LabelSecurityCalendar;
public static String LabelSecurityCalendarToolTip;
public static String LabelUseExistingSecurity;
public static String LabelSelectedTransactions;
public static String LabelSelectYear;
public static String LabelSelectYearSince;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,12 @@ protected Control createDialogArea(Composite parent)
input.setFocus(); // when text input visible, set focus
}

Label label = new Label(container, SWT.NONE | SWT.WRAP);
label.setText(this.message);
GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(label);
if (message != null && !message.isEmpty())
{
Label label = new Label(container, SWT.NONE | SWT.WRAP);
label.setText(this.message);
GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(label);
}

searchText = new Text(container, SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(searchText);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,8 @@ LabelSecurityPerformance = Security Performance

LabelSecurityTransfer = Security transfer

LabelUseExistingSecurity = Use existing security...

LabelSelectYear = Other year...

LabelSelectYearSince = Since
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1676,6 +1676,8 @@ LabelUpdatedConfiguration = Aktualizovan\u00E1 konfigurace

LabelUpdatesAvailable = K dispozici je nov\u00E1 verze

LabelUseExistingSecurity = Pou\u017Eijte st\u00E1vaj\u00EDc\u00ED bezpe\u010Dnostn\u00ED...

LabelUseGrossValue = Pou\u017Eijte hrubou hodnotu

LabelUsingDashboardDefaultReportingPeriod = Dashboard vykazovan\u00E9ho obdob\u00ED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,8 @@ LabelUpdatedConfiguration = Opdateret konfiguration

LabelUpdatesAvailable = Opdateringer tilg\u00E6ngelig

LabelUseExistingSecurity = Brug eksisterende sikkerhed...

LabelUseGrossValue = Brug bruttov\u00E6rdi

LabelUsingDashboardDefaultReportingPeriod = Brugergr\u00E6nseflade rapporteringsperiode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,8 @@ LabelUpdatedConfiguration = Aktualisierte Konfiguration

LabelUpdatesAvailable = Eine neue Version ist verf\u00FCgbar

LabelUseExistingSecurity = Vorhandenes Wertpapier verwenden...

LabelUseGrossValue = Bruttowert verwenden

LabelUsingDashboardDefaultReportingPeriod = Dashboard-Zeitraum
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,8 @@ LabelUpdatedConfiguration = Configuraci\u00F3n actualizada

LabelUpdatesAvailable = Actualizaciones Disponibles

LabelUseExistingSecurity = Utilizar la seguridad existente...

LabelUseGrossValue = Usar valor bruto

LabelUsingDashboardDefaultReportingPeriod = Periodo de reporte del Dashboard
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1670,6 +1670,8 @@ LabelUpdatedConfiguration = Configuration mise \u00E0 jour

LabelUpdatesAvailable = Mise \u00E0 jour disponible

LabelUseExistingSecurity = Utiliser un titre existant...

LabelUseGrossValue = Utiliser valeur brute

LabelUsingDashboardDefaultReportingPeriod = Tableau de bord p\u00E9riode courante
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,8 @@ LabelUpdatedConfiguration = Configurazione aggiornata

LabelUpdatesAvailable = Aggiornamenti Disponibili

LabelUseExistingSecurity = Utilizzare la sicurezza esistente...

LabelUseGrossValue = Usa valore lordo

LabelUsingDashboardDefaultReportingPeriod = Periodo rendicontazione dashboard
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,8 @@ LabelUpdatedConfiguration = Bijgewerkte configuratie

LabelUpdatesAvailable = Beschikbare updates

LabelUseExistingSecurity = Gebruik bestaande beveiliging...

LabelUseGrossValue = Gebruik bruto waarde

LabelUsingDashboardDefaultReportingPeriod = Dashboard-rapportageperiode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,8 @@ LabelUpdatedConfiguration = Zaktualizowana konfiguracja

LabelUpdatesAvailable = Dost\u0119pne aktualizacje

LabelUseExistingSecurity = Wykorzystaj istniej\u0105ce zabezpieczenia...

LabelUseGrossValue = U\u017Cyj warto\u015Bci brutto

LabelUsingDashboardDefaultReportingPeriod = Okres raportowania panelu
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,8 @@ LabelUpdatedConfiguration = Configura\u00E7\u00E3o actualizada

LabelUpdatesAvailable = Atualiza\u00E7\u00F5es dispon\u00EDveis

LabelUseExistingSecurity = Utilizar a seguran\u00E7a existente...

LabelUseGrossValue = Usar valor bruto

LabelUsingDashboardDefaultReportingPeriod = Per\u00EDodo do relat\u00F3rio do painel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1673,6 +1673,8 @@ LabelUpdatedConfiguration = \u041E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u04

LabelUpdatesAvailable = \u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B \u041E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F

LabelUseExistingSecurity = \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430 \u0437\u0430\u0449\u0438\u0442\u044B...

LabelUseGrossValue = \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C \u0431\u0440\u0443\u0442\u0442\u043E

LabelUsingDashboardDefaultReportingPeriod = \u041E\u0442\u0447\u0435\u0442\u043D\u044B\u0439 \u043F\u0435\u0440\u0438\u043E\u0434 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439 \u043F\u0430\u043D\u0435\u043B\u0438
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,8 @@ LabelUpdatedConfiguration = Aktualizovan\u00E1 konfigur\u00E1cia

LabelUpdatesAvailable = Dostupn\u00E9 aktualiz\u00E1cie

LabelUseExistingSecurity = Pou\u017Eite existuj\u00FAce bezpe\u010Dnostn\u00E9...

LabelUseGrossValue = Pou\u017Eite hrub\u00FA hodnotu

LabelUsingDashboardDefaultReportingPeriod = Dashboard vykazovan\u00E9ho obdobia
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,8 @@ LabelUpdatedConfiguration = \u66F4\u65B0\u914D\u7F6E

LabelUpdatesAvailable = \u6709\u53EF\u7528\u66F4\u65B0

LabelUseExistingSecurity = \u5229\u7528\u73B0\u6709\u7684\u5B89\u5168\u8BBE\u5907\u548C\u6280\u672F

LabelUseGrossValue = \u4F7F\u7528\u603B\u989D

LabelUsingDashboardDefaultReportingPeriod = \u62A5\u8868\u62A5\u544A\u671F
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import name.abuchen.portfolio.datatransfer.Extractor;
import name.abuchen.portfolio.datatransfer.Extractor.Item;
import name.abuchen.portfolio.datatransfer.SecurityCache;
import name.abuchen.portfolio.datatransfer.actions.InsertAction;
import name.abuchen.portfolio.datatransfer.csv.CSVConfig;
import name.abuchen.portfolio.datatransfer.csv.CSVConfigManager;
import name.abuchen.portfolio.datatransfer.csv.CSVImporter;
Expand All @@ -25,7 +24,6 @@
import name.abuchen.portfolio.model.SecurityPrice;
import name.abuchen.portfolio.ui.Images;
import name.abuchen.portfolio.ui.Messages;
import name.abuchen.portfolio.ui.jobs.ConsistencyChecksJob;
import name.abuchen.portfolio.ui.wizards.AbstractWizardPage;

public class CSVImportWizard extends Wizard
Expand Down Expand Up @@ -168,17 +166,15 @@ public boolean performFinish()
{
((AbstractWizardPage) getContainer().getCurrentPage()).afterPage();

boolean isDirty = false;

if (importer.getExtractor() == importer.getSecurityPriceExtractor())
isDirty = importSecurityPrices();
{
var isDirty = importSecurityPrices();
if (isDirty)
client.markDirty();
}
else
isDirty = importItems();

if (isDirty)
{
client.markDirty();
new ConsistencyChecksJob(client, false).schedule();
new ImportController(client).perform(List.of(reviewPage));
}

return true;
Expand All @@ -202,24 +198,4 @@ private boolean importSecurityPrices()
}
return isDirty;
}

private boolean importItems()
{
InsertAction action = new InsertAction(client);
action.setConvertBuySellToDelivery(reviewPage.doConvertToDelivery());
action.setRemoveDividends(reviewPage.doRemoveDividends());

boolean isDirty = false;
for (ExtractedEntry entry : reviewPage.getEntries())
{
if (entry.isImported())
{
entry.getItem().apply(action, reviewPage);
isDirty = true;
}
}

return isDirty;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import name.abuchen.portfolio.datatransfer.Extractor.Item;
import name.abuchen.portfolio.datatransfer.ImportAction;
import name.abuchen.portfolio.datatransfer.ImportAction.Status;
import name.abuchen.portfolio.model.Security;

public class ExtractedEntry
{
Expand All @@ -17,6 +18,19 @@ public class ExtractedEntry
private Status.Code maxCode = Status.Code.OK;
private List<Status> status = new ArrayList<>();

/**
* If non null, the security dependency tells which other extracted items
* represents the security which this extracted items (typically a
* transactions) requires.
*/
private ExtractedEntry securityDependency;

/**
* If non null, then the security dependency is overwritten by the given
* security.
*/
private Security securityOverride;

public ExtractedEntry(Item item)
{
this.item = item;
Expand All @@ -31,18 +45,23 @@ public void setImported(boolean isImported)
{
this.isImported = isImported;
}

public boolean isImported()
{
// do not import if explicitly excluded by the user
if (isImported != null && !isImported.booleanValue())
return false;

// do not import if the entry has a dependency which is not imported
// while there is no security override
if (securityDependency != null && !securityDependency.isImported() && securityOverride == null)
return false;

// otherwise import if either the status is OK or the user explicitly
// overrides warnings
return maxCode == Status.Code.OK
|| (maxCode == Status.Code.WARNING && isImported != null && isImported.booleanValue()
|| (maxCode == Status.Code.WARNING && item.isInvestmentPlanItem()));
|| (maxCode == Status.Code.WARNING && item.isInvestmentPlanItem()));
Comment on lines 62 to +64
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe that way better for understanding the code?

    // Import if the status is OK or the user explicitly overrides warnings
    if (maxCode == Status.Code.OK) {
        return true;
    }

    // Import if warnings are explicitly allowed or if it's an investment plan item
    return maxCode == Status.Code.WARNING && (isImported != null && isImported.booleanValue()
            || item.isInvestmentPlanItem());

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was only a formatting change - maybe I should remove even the formatting from the commit.

I am also not sure if the statements are identical due to the missing parenthesis.

}

public void addStatus(ImportAction.Status status)
Expand All @@ -67,4 +86,24 @@ public void clearStatus()
this.status.clear();
this.maxCode = Status.Code.OK;
}
}

public ExtractedEntry getSecurityDependency()
{
return securityDependency;
}

public void setSecurityDependency(ExtractedEntry securityDependency)
{
this.securityDependency = securityDependency;
}

public Security getSecurityOverride()
{
return securityOverride;
}

public void setSecurityOverride(Security securityOverride)
{
this.securityOverride = securityOverride;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package name.abuchen.portfolio.ui.wizards.datatransfer;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.widgets.Display;

import name.abuchen.portfolio.datatransfer.Extractor;
import name.abuchen.portfolio.datatransfer.actions.InsertAction;
import name.abuchen.portfolio.model.Client;
import name.abuchen.portfolio.model.Security;
import name.abuchen.portfolio.ui.jobs.ConsistencyChecksJob;
import name.abuchen.portfolio.ui.jobs.UpdateQuotesJob;
import name.abuchen.portfolio.ui.util.swt.ActiveShell;
import name.abuchen.portfolio.ui.wizards.security.FindQuoteProviderDialog;

public class ImportController
{

private final Client client;

public ImportController(Client client)
{
this.client = client;
}

public void perform(List<ReviewExtractedItemsPage> pages)
{
if (pages.isEmpty())
return;

var newSecurities = new ArrayList<Security>();

var isDirty = false;
for (ReviewExtractedItemsPage page : pages)
{
page.afterPage();
var isPageDirty = importPage(page, newSecurities);
isDirty |= isPageDirty;
}

if (isDirty)
{
client.markDirty();

// run consistency checks in case bogus transactions have been
// created (say: an outbound delivery of a security where there
// no held shares)
new ConsistencyChecksJob(client, false).schedule();
}

if (!newSecurities.isEmpty())
{
// updated prices for newly created securities (for example
// crypto currencies already have a working configuration)

new UpdateQuotesJob(client, newSecurities).schedule();

// run async to allow the other dialog to close

Display.getDefault().asyncExec(() -> {
FindQuoteProviderDialog dialog = new FindQuoteProviderDialog(ActiveShell.get(), client, newSecurities);
dialog.open();
});
}
}

private boolean importPage(ReviewExtractedItemsPage page, ArrayList<Security> newSecurities)
{
var isDirty = false;

InsertAction action = new InsertAction(client);
action.setConvertBuySellToDelivery(page.doConvertToDelivery());
action.setRemoveDividends(page.doRemoveDividends());

for (ExtractedEntry entry : page.getEntries())
{
if (entry.isImported())
{
action.setInvestmentPlanItem(entry.getItem().isInvestmentPlanItem());

// apply security override
if (entry.getSecurityOverride() != null)
entry.getItem().setSecurity(entry.getSecurityOverride());

entry.getItem().apply(action, page);
isDirty = true;

if (entry.getItem() instanceof Extractor.SecurityItem)
{
newSecurities.add(entry.getItem().getSecurity());
}
}
}
return isDirty;
}
}
Loading