/**
   * Get the weixin order according to specific extra condition{@link ExtraCond}.
   *
   * @param dbCon the database connection
   * @param staff the staff to perform this action
   * @param extraCond the extra condition {@link ExtraCond}
   * @return the result to wx order
   * @throws SQLException throws if failed to execute any SQL statement
   */
  public static List<WxOrder> getByCond(
      DBCon dbCon, Staff staff, ExtraCond extraCond, String orderClause) throws SQLException {
    String sql;
    sql =
        " SELECT * FROM "
            + Params.dbName
            + ".weixin_order "
            + " WHERE 1 = 1 "
            + " AND restaurant_id = "
            + staff.getRestaurantId()
            + (extraCond != null ? extraCond.toString() : " ")
            + (orderClause != null ? orderClause : "");
    dbCon.rs = dbCon.stmt.executeQuery(sql);

    List<WxOrder> result = new ArrayList<WxOrder>();
    while (dbCon.rs.next()) {
      WxOrder wxOrder = new WxOrder(dbCon.rs.getInt("wx_order_id"));
      wxOrder.setRestaurant(dbCon.rs.getInt("restaurant_id"));
      wxOrder.setStatus(WxOrder.Status.valueOf(dbCon.rs.getInt("status")));
      wxOrder.setType(WxOrder.Type.valueOf(dbCon.rs.getInt("type")));
      if (wxOrder.getType() == WxOrder.Type.TAKE_OUT) {
        TakeoutAddress address = new TakeoutAddress(dbCon.rs.getInt("address_id"));
        address.setAddress(dbCon.rs.getString("address"));
        wxOrder.setTakoutAddress(address);
      }
      wxOrder.setCode(dbCon.rs.getInt("code"));
      wxOrder.setOrderId(dbCon.rs.getInt("order_id"));
      wxOrder.setBirthDate(dbCon.rs.getTimestamp("birth_date").getTime());
      wxOrder.setWeixinSerial(dbCon.rs.getString("weixin_serial"));
      result.add(wxOrder);
    }
    dbCon.rs.close();

    return result;
  }
  /**
   * Insert the new weixin order for take out according to builder {@link
   * WxOrder#InsertBuilder4Takeout}.
   *
   * @param dbCon the database connection
   * @param staff the staff to perform this action
   * @param builder the builder {@link WxOrder#InsertBuilder4Takeout}
   * @return the id to weixin order just inserted
   * @throws SQLException throws if failed to execute any SQL statement
   * @throws BusinessException throws if the take-out address to this order does NOT exist
   */
  public static int insert(DBCon dbCon, Staff staff, WxOrder.InsertBuilder4Takeout builder)
      throws SQLException, BusinessException {
    WxOrder wxOrder = builder.build();

    Member member = MemberDao.getByWxSerial(dbCon, staff, wxOrder.getWeixinSerial());
    if (TakeoutAddressDao.getByCond(
            dbCon,
            staff,
            new TakeoutAddressDao.ExtraCond()
                .setMember(member)
                .setId(wxOrder.getTakeoutAddress().getId()))
        .isEmpty()) {
      throw new BusinessException("外卖地址信息不属于此会员", WxOrderError.WX_TAKE_OUT_ORDER_NOT_ALLOW);
    }

    wxOrder.setTakoutAddress(
        TakeoutAddressDao.getById(dbCon, staff, wxOrder.getTakeoutAddress().getId()));

    int id = insert(dbCon, staff, wxOrder);
    String sql;
    sql =
        " UPDATE "
            + Params.dbName
            + ".weixin_order SET "
            + " wx_order_id = "
            + id
            + " ,address_id = "
            + wxOrder.getTakeoutAddress().getId()
            + " ,address = '"
            + wxOrder.getTakeoutAddress().getAddress()
            + "'"
            + " WHERE wx_order_id = "
            + id;
    dbCon.stmt.executeUpdate(sql);

    // Update the last used to take-out address
    sql =
        " UPDATE "
            + Params.dbName
            + ".take_out_address SET "
            + " last_used = NOW() "
            + " WHERE id = "
            + wxOrder.getTakeoutAddress().getId();
    dbCon.stmt.executeUpdate(sql);

    return id;
  }