public boolean preloadTariffAreas() {
   try {
     logger.log(Level.INFO, "Preloading tariff areas");
     ServerLoader loader = new ServerLoader();
     ServerLoader.Response r = loader.read("TariffAreasAPI", "getAll");
     if (r.getStatus().equals(ServerLoader.Response.STATUS_OK)) {
       JSONArray a = r.getArrayContent();
       Map<Integer, Map<String, Double>> prices = new HashMap<Integer, Map<String, Double>>();
       List<TariffInfo> areas = new ArrayList<TariffInfo>();
       for (int i = 0; i < a.length(); i++) {
         JSONObject o = a.getJSONObject(i);
         TariffInfo area = new TariffInfo(o);
         areas.add(area);
         Map<String, Double> areaPrices = new HashMap<String, Double>();
         JSONArray aPrices = o.getJSONArray("prices");
         for (int j = 0; j < aPrices.length(); j++) {
           JSONObject oPrice = aPrices.getJSONObject(j);
           String prdId = oPrice.getString("productId");
           double price = oPrice.getDouble("price");
           areaPrices.put(prdId, price);
         }
         prices.put(area.getID(), areaPrices);
       }
       TariffAreasCache.refreshTariffAreas(areas);
       TariffAreasCache.refreshPrices(prices);
       return true;
     } else {
       return false;
     }
   } catch (Exception e) {
     e.printStackTrace();
     return false;
   }
 }
 public boolean preloadCategories() {
   try {
     logger.log(Level.INFO, "Preloading categories");
     ServerLoader loader = new ServerLoader();
     ServerLoader.Response r = loader.read("CategoriesAPI", "getAll");
     if (r.getStatus().equals(ServerLoader.Response.STATUS_OK)) {
       JSONArray a = r.getArrayContent();
       List<CategoryInfo> categories = new ArrayList<CategoryInfo>();
       for (int i = 0; i < a.length(); i++) {
         JSONObject o = a.getJSONObject(i);
         CategoryInfo cat = new CategoryInfo(o);
         categories.add(cat);
         try {
           if (o.getBoolean("hasImage")) {
             byte[] img = this.loadImage(TYPE_CAT, cat.getID());
             CatalogCache.storeCategoryImage(cat.getID(), img);
           }
         } catch (BasicException e) {
           logger.log(Level.WARNING, "Unable to get category image for " + cat.getID(), e);
         }
       }
       CatalogCache.refreshCategories(categories);
       return true;
     } else {
       return false;
     }
   } catch (Exception e) {
     e.printStackTrace();
     return false;
   }
 }
 public boolean saveMove(CashMove move) throws BasicException {
   try {
     ServerLoader loader = new ServerLoader();
     ServerLoader.Response r =
         loader.write(
             "CashMvtsAPI",
             "move",
             "cashId",
             move.getCashId(),
             "date",
             String.valueOf(DateUtils.toSecTimestamp(move.getDate())),
             "note",
             move.getNote(),
             "payment",
             move.getPayment().toJSON().toString());
     if (r.getStatus().equals(ServerLoader.Response.STATUS_OK)) {
       return true;
     } else {
       return false;
     }
   } catch (Exception e) {
     e.printStackTrace();
     throw new BasicException(e);
   }
 }
 public boolean preloadTaxes() {
   try {
     logger.log(Level.INFO, "Preloading taxes");
     ServerLoader loader = new ServerLoader();
     ServerLoader.Response r = loader.read("TaxesAPI", "getAll");
     if (r.getStatus().equals(ServerLoader.Response.STATUS_OK)) {
       JSONArray a = r.getArrayContent();
       List<TaxCategoryInfo> taxCats = new ArrayList<TaxCategoryInfo>();
       List<TaxInfo> taxes = new ArrayList<TaxInfo>();
       for (int i = 0; i < a.length(); i++) {
         JSONObject o = a.getJSONObject(i);
         TaxCategoryInfo taxCat = new TaxCategoryInfo(o);
         taxCats.add(taxCat);
         JSONArray a2 = o.getJSONArray("taxes");
         for (int j = 0; j < a2.length(); j++) {
           JSONObject o2 = a2.getJSONObject(j);
           TaxInfo tax = new TaxInfo(o2);
           taxes.add(tax);
         }
       }
       TaxesCache.refreshTaxCategories(taxCats);
       TaxesCache.refreshTaxes(taxes);
       return true;
     } else {
       return false;
     }
   } catch (Exception e) {
     e.printStackTrace();
     return false;
   }
 }
 public boolean preloadProducts() {
   try {
     logger.log(Level.INFO, "Preloading products");
     ServerLoader loader = new ServerLoader();
     ServerLoader.Response r = loader.read("ProductsAPI", "getAll");
     if (r.getStatus().equals(ServerLoader.Response.STATUS_OK)) {
       JSONArray a = r.getArrayContent();
       List<ProductInfoExt> products = new ArrayList<ProductInfoExt>();
       for (int i = 0; i < a.length(); i++) {
         JSONObject o = a.getJSONObject(i);
         if (!o.getBoolean("visible")) {
           // Don't add products not sold
           continue;
         }
         ProductInfoExt prd = new ProductInfoExt(o);
         products.add(prd);
         try {
           if (o.getBoolean("hasImage")) {
             byte[] img = this.loadImage(TYPE_PRD, prd.getID());
             CatalogCache.storeProductImage(prd.getID(), img);
           }
         } catch (BasicException e) {
           logger.log(Level.WARNING, "Unable to get product image for " + prd.getID(), e);
         }
       }
       CatalogCache.refreshProducts(products);
       return true;
     } else {
       return false;
     }
   } catch (Exception e) {
     e.printStackTrace();
     return false;
   }
 }
 private byte[] loadImage(String type, String id) {
   try {
     ServerLoader loader = new ServerLoader();
     return loader.readBinary(type, id);
   } catch (Exception e) {
     e.printStackTrace();
     return null;
   }
 }
 public void deleteTicket(TicketInfo ticket) throws BasicException {
   try {
     ServerLoader loader = new ServerLoader();
     ServerLoader.Response r;
     r = loader.write("TicketsAPI", "delete", "id", ticket.getId());
     if (!r.getStatus().equals(ServerLoader.Response.STATUS_OK)) {
       throw new BasicException("Bad server response");
     }
   } catch (Exception e) {
     e.printStackTrace();
     throw new BasicException(e);
   }
 }
 // Tickets and Receipt list
 public List<TicketInfo> searchTickets(
     Integer ticketId,
     Integer ticketType,
     String cashId,
     Date start,
     Date stop,
     String customerId,
     String userId)
     throws BasicException {
   try {
     ServerLoader loader = new ServerLoader();
     ServerLoader.Response r =
         loader.read(
             "TicketsAPI",
             "search",
             "ticketId",
             ticketId != null ? ticketId.toString() : null,
             "ticketType",
             ticketType != null ? ticketType.toString() : null,
             "cashId",
             cashId,
             "dateStart",
             start != null ? String.valueOf(DateUtils.toSecTimestamp(start)) : null,
             "dateStop",
             stop != null ? String.valueOf(DateUtils.toSecTimestamp(stop)) : null,
             "customerId",
             customerId,
             "userId",
             userId);
     if (r.getStatus().equals(ServerLoader.Response.STATUS_OK)) {
       JSONArray a = r.getArrayContent();
       List<TicketInfo> list = new ArrayList<TicketInfo>();
       for (int i = 0; i < a.length(); i++) {
         JSONObject o = a.getJSONObject(i);
         list.add(new TicketInfo(o));
       }
       return list;
     } else {
       return null;
     }
   } catch (Exception e) {
     e.printStackTrace();
     throw new BasicException(e);
   }
 }
 public ZTicket getZTicket(String cashSessionId) throws BasicException {
   try {
     ServerLoader loader = new ServerLoader();
     ServerLoader.Response r = loader.read("CashesAPI", "zticket", "id", cashSessionId);
     if (r.getStatus().equals(ServerLoader.Response.STATUS_OK)) {
       JSONObject o = r.getObjContent();
       if (o == null) {
         return null;
       } else {
         return new ZTicket(o);
       }
     } else {
       return null;
     }
   } catch (Exception e) {
     e.printStackTrace();
     throw new BasicException(e);
   }
 }
 /** Get the list of tickets from opened cash sessions. */
 public List<TicketInfo> getSessionTickets() throws BasicException {
   try {
     ServerLoader loader = new ServerLoader();
     ServerLoader.Response r = loader.read("TicketsAPI", "getOpen");
     if (r.getStatus().equals(ServerLoader.Response.STATUS_OK)) {
       JSONArray a = r.getArrayContent();
       List<TicketInfo> list = new ArrayList<TicketInfo>();
       for (int i = 0; i < a.length(); i++) {
         JSONObject o = a.getJSONObject(i);
         list.add(new TicketInfo(o));
       }
       return list;
     } else {
       return null;
     }
   } catch (Exception e) {
     e.printStackTrace();
     throw new BasicException(e);
   }
 }
 /** Save or edit ticket */
 public final void saveTicket(
     final TicketInfo ticket, final String locationId, final String cashId) throws BasicException {
   if (CallQueue.isOffline()) {
     // Don't try to send and wait for recovery
     CallQueue.queueTicketSave(ticket);
     return;
   }
   try {
     ServerLoader loader = new ServerLoader();
     ServerLoader.Response r;
     r =
         loader.write(
             "TicketsAPI", "save", "ticket", ticket.toJSON().toString(), "cashId", cashId);
     if (!r.getStatus().equals(ServerLoader.Response.STATUS_OK)) {
       throw new BasicException("Bad server response");
     }
   } catch (Exception e) {
     // Unable to save, queue it
     logger.log(Level.WARNING, "Unable to save ticket: " + e.getMessage());
     CallQueue.queueTicketSave(ticket);
     throw new BasicException(e);
   }
 }
 public boolean preloadCurrencies() {
   try {
     logger.log(Level.INFO, "Preloading currencies");
     ServerLoader loader = new ServerLoader();
     ServerLoader.Response r = loader.read("CurrenciesAPI", "getAll");
     if (r.getStatus().equals(ServerLoader.Response.STATUS_OK)) {
       JSONArray a = r.getArrayContent();
       List<CurrencyInfo> currencies = new ArrayList<CurrencyInfo>();
       for (int i = 0; i < a.length(); i++) {
         JSONObject o = a.getJSONObject(i);
         CurrencyInfo currency = new CurrencyInfo(o);
         currencies.add(currency);
       }
       CurrenciesCache.refreshCurrencies(currencies);
       return true;
     } else {
       return false;
     }
   } catch (Exception e) {
     e.printStackTrace();
     return false;
   }
 }
 public boolean preloadCompositions() {
   try {
     logger.log(Level.INFO, "Preloading compositions");
     ServerLoader loader = new ServerLoader();
     ServerLoader.Response r = loader.read("CompositionsAPI", "getAll");
     if (r.getStatus().equals(ServerLoader.Response.STATUS_OK)) {
       JSONArray a = r.getArrayContent();
       Map<String, List<SubgroupInfo>> compos = new HashMap<String, List<SubgroupInfo>>();
       Map<Integer, List<String>> groups = new HashMap<Integer, List<String>>();
       for (int i = 0; i < a.length(); i++) {
         JSONObject o = a.getJSONObject(i);
         String prdId = o.getString("id");
         compos.put(prdId, new ArrayList<SubgroupInfo>());
         JSONArray grps = o.getJSONArray("groups");
         for (int j = 0; j < grps.length(); j++) {
           JSONObject oGrp = grps.getJSONObject(j);
           SubgroupInfo subgrp = new SubgroupInfo(oGrp);
           compos.get(prdId).add(subgrp);
           groups.put(subgrp.getID(), new ArrayList<String>());
           JSONArray choices = oGrp.getJSONArray("choices");
           for (int k = 0; k < choices.length(); k++) {
             JSONObject oPrd = choices.getJSONObject(k);
             groups.get(subgrp.getID()).add(oPrd.getString("productId"));
           }
         }
       }
       CatalogCache.refreshSubgroups(compos);
       CatalogCache.refreshSubgroupProds(groups);
       return true;
     } else {
       return false;
     }
   } catch (Exception e) {
     e.printStackTrace();
     return false;
   }
 }