package com.jbidwatcher.ui.table; import com.jbidwatcher.auction.AuctionEntry; import com.jbidwatcher.auction.Seller; import com.jbidwatcher.util.Currency; import com.jbidwatcher.util.config.JConfig; import java.util.HashMap; import java.util.Map; /** * Holds the sortable methods for an AuctionEntry. This is a featherweight; containing the current auction entry to be processed * rather than creating a new one every time we need to do a lookup. This also caches seller information, which may not be a great * choice on long-running instances. * * Created by mschweers on 8/1/14. */ class AuctionSortable { private AuctionEntry entry; private static Map<String, Seller> sellers = new HashMap<String, Seller>(); public AuctionSortable() { } public void setEntry(AuctionEntry ae) { entry = ae; } /** Utility methods **/ private Seller getSeller(String sellerId) { Seller seller; if(sellers.containsKey(sellerId)) { seller = sellers.get(sellerId); } else { seller = Seller.findFirstBy("id", sellerId); sellers.put(sellerId, seller); } return seller; } private int safeConvert(String feedbackPercent) { int rval; try { rval = (int) (Double.parseDouble(feedbackPercent) * 10.0); } catch (NumberFormatException e) { rval = 0; } return rval; } private Currency getMaxOrSnipe(AuctionEntry aEntry) { if(aEntry.isSniped()) { return aEntry.getSnipeAmount(); } if(aEntry.isBidOn()) { return aEntry.getBid(); } if(aEntry.snipeCancelled() && aEntry.isComplete()) { return aEntry.getCancelledSnipe(); } return Currency.NoValue(); } /** Key methods **/ /** * Get the auction's identifier. * * @return The auction's identifier. */ public String getId() { return entry.getIdentifier(); } /** * Get a sortable currency (USD) equivalent to the current high bid on a listing. * * @return The current high bid in USD, falling back to the 'buy now' if it's not an auction. It could, but shouldn't, return Currency.NoValue(). */ public Currency getCurrentBid() { if(entry.getDefaultCurrency().getCurrencyType() == Currency.US_DOLLAR) { return entry.getCurrentPrice(); } Currency rval = entry.getUSCurBid(); if(rval.getValue() == 0.0 && rval.getCurrencyType() == Currency.US_DOLLAR) { return entry.getCurrentUSPrice(); } return rval; } /** * Get a sortable currency (USD) equivalent to either the current snipe (if there is one) or the current user's max bid (if they have one). * * @return The current snipe or the user's maximum bid (in that order) converted to USD for sorting. Currency.NoValue() if neither is present. */ public Currency getSnipeOrMax() { return Currency.convertToUSD(entry.getCurrentUSPrice(), entry.getCurrentPrice(), getMaxOrSnipe(entry)); } /** * If the listing has a fixed price component, return a sortable currency (USD) equivalent of that fixed price amount. * * @return The buy-now amount of a listing, converted to USD for sorting purposes, or null if no fixed price amount is found. */ public Currency getFixedPrice() { return Currency.convertToUSD(entry.getCurrentUSPrice(), entry.getCurrentPrice(), entry.getBuyNow()); } /** * Get the sortable currency (USD) equivalent of the shipping amount (including optional insurance), or Currency.NoValue() if none found. * * @return The shipping amount (with optional insurance), converted to USD or Currency.NoValue() if the shipping amount couldn't be determined. */ public Currency getShippingInsurance() { Currency si = (!entry.getShipping().isNull())?entry.getShippingWithInsurance(): Currency.NoValue(); // This is crack. I'm insane to even think about doing this, but it works... return Currency.convertToUSD(entry.getCurrentUSPrice(), entry.getCurrentPrice(), si); } /** * Get the sortable currency (USD) equivalent of the current high bid by the current user. * * @return The current high bid by the user, in a canonicalized currency (USD) for sorting purposes, or Currency.NoValue() if none found. */ public Currency getMax() { Currency bid = entry.isBidOn()?entry.getBid(): Currency.NoValue(); return Currency.convertToUSD(entry.getCurrentUSPrice(), entry.getCurrentPrice(), bid); } /** * Get the snipe amount set (if any) and convert it to a sortable currency, USD. * * @return The USD equivalent of the snipe amount, or null if no snipe amount has been provided. */ public Currency getSnipe() { Currency snipe = entry.getSnipeAmount(); return Currency.convertToUSD(entry.getCurrentUSPrice(), entry.getCurrentPrice(), snipe); } /** * Get the seller's feedback as an integer representing a percentage. * * @return The percentage of positive feedbacks the seller of this auction entry has received, or 0 if that number is not available. */ public int getSellerPositiveFeedback() { Seller seller = getSeller(entry.getSellerId()); try { String feedbackPercent = seller.getPositivePercentage(); if(feedbackPercent != null) feedbackPercent = feedbackPercent.replace("%", ""); return safeConvert(feedbackPercent); } catch(Exception e) { return 0; } } /** * Get any comment that has been assigned to this entry. * * @return The comment for the auction entry, or the empty string if no comment has been assigned. */ public String getComment() { String s = entry.getComment(); return (s==null?"":s); } /** * Get the seller's feedback as an integer. * * @return The current entry's seller's total (non-percentage) feedback score. */ public int getSellerFeedback() { Seller seller = getSeller(entry.getSellerId()); return seller.getFeedback(); } /** * Get a sortable equivalent of the current price plus shipping. This converts to USD if possible, as a common converter, so all * currency values can be sorted against each other. * * @return Currency.NoValue() if the shipping is not set, or if the USD conversion of the shipping can't be added to the USD * conversion of the current price, otherwise the USD equivalent of the sum of shipping + current price. */ public Currency getCurrentTotal() { Currency shipping = entry.getShippingWithInsurance(); if (shipping.getCurrencyType() == Currency.NONE) { return shipping; // shipping not set so cannot add up values } Currency shippingUSD = Currency.convertToUSD(entry.getCurrentUSPrice(), entry.getCurrentPrice(), entry.getShippingWithInsurance()); try { return entry.getUSCurBid().add(shippingUSD); } catch (Currency.CurrencyTypeException e) { JConfig.log().handleException("Threw a bad currency exception, which should be unlikely.", e); //$NON-NLS-1$ return Currency.NoValue(); } } /** * Get a sortable version of the snipe+shipping. This converts to USD if possible, as a common converter, so all currency values * can be sorted against each other. * * @return Currency.NoValue() if the shipping is not set, or there's a problem adding the USD shipping to the USD-converted snipe, * otherwise returns the sum of the USD equivalents of any snipe set and the shipping (with insurance). */ public Currency getSnipeTotal() { Currency shipping = entry.getShippingWithInsurance(); if (shipping.getCurrencyType() == Currency.NONE) { return shipping; // shipping not set so cannot add up values } Currency shippingUSD = Currency.convertToUSD(entry.getCurrentUSPrice(), entry.getCurrentPrice(), entry.getShippingWithInsurance()); try { return Currency.convertToUSD(entry.getCurrentUSPrice(), entry.getCurrentPrice(), entry.getSnipeAmount()).add(shippingUSD); } catch (Currency.CurrencyTypeException e) { JConfig.log().handleException("Currency addition or conversion threw a bad currency exception, which should be unlikely.", e); //$NON-NLS-1$ return Currency.NoValue(); } } }