horizon/resources/lots.js

import { ResourceGroupBase } from '../../resource_group_base'
import { SUBMIT_TRANSACTION_TIMEOUT } from '../constants'
import { safeAccountId } from '../../utils/safe_account_id'

/**
 * Lots.
 *
 * @class
 */
export class Lots extends ResourceGroupBase {
  /**
   * Create a lot. Creation might need approval depending on the account type.
   *
   * @param {object} lot Lot data.
   * @param {string} lot.type Lot type.
   * @param {string} lot.currency Lot currency.
   * @param {string} lot.startPrice Start price in lot currency.
   * @param {string} [lot.deposit] Desired deposit amount in lot currency.
   * @param {string} [lot.buyNowPrice] "Buy Now" price in lot currency.
   * @param {string} [lot.minStep] Minimal bid increment in lot currency. For 'eng' auctions only.
   * @param {string} [lot.maxStep] Maximal bid increment in lot currency. For 'eng' auctions only.
   * @param {number} [lot.startTime] Auction start time. Unix timestamp in seconds.
   * @param {number} [lot.duration] Auction duration. In seconds.
   * @param {object} [lot.details] Lot details.
   *
   * @return {Promise<JsonApiResponse>}
   */
  create (lot) {
    return this
      ._makeCallBuilder()
      .withCredentials()
      .withTimeout(SUBMIT_TRANSACTION_TIMEOUT)
      .post({
        data: {
          type: 'lots',
          attributes: lot
        }
      })
  }

  /**
   * Close the lot.
   *
   * @param {string} lotId ID of the lot.
   * @param {string} state New lot state.
   *
   * @return {Promise.<JsonApiResponse>}
   */
  close (lotId, state) {
    return this
      ._makeCallBuilder()
      .withCredentials()
      .withTimeout(SUBMIT_TRANSACTION_TIMEOUT)
      .appendUrlSegment('closed')
      .post({
        data: {
          id: lotId,
          type: 'lots',
          attributes: { state }
        }
      })
  }

  /**
   * Manage auction participant.
   *
   * @param {string} lotId ID of the lot.
   * @param {string} participantId ID of the participant to be rejected.
   *
   * @return {Promise.<JsonApiResponse>}
   */
  rejectParticipant (lotId, participantId) {
    return this._makeLotCallBuilder(lotId)
      .appendUrlSegment(['participants', participantId])
      .withCredentials()
      .withTimeout(SUBMIT_TRANSACTION_TIMEOUT)
      .delete()
  }

  /**
   * Participate in auction or sale.
   *
   * @param {string} lotId ID of the lot.
   * @param {boolean} [buyNow=false] Request "Buy Now" if true.
   *
   * @return {Promise.<JsonApiResponse>}
   */
  participate (lotId, buyNow = false) {
    return this
      ._makeLotCallBuilder(lotId)
      .withCredentials()
      .withTimeout(SUBMIT_TRANSACTION_TIMEOUT)
      .appendUrlSegment('participation_requests')
      .post({
        data: {
          type: 'participation_requests',
          attributes: {
            lotId,
            buyNow
          }
        }
      })
  }

  /**
   * Submit a bid.
   *
   * @param {string} lotId ID of the lot.
   * @param {string} amount Bid amount in lot currency.
   *
   * @return {Promise.<JsonApiResponse>}
   */
  submitBid (lotId, amount) {
    return this
      ._makeLotCallBuilder(lotId)
      .withCredentials()
      .withTimeout(SUBMIT_TRANSACTION_TIMEOUT)
      .appendUrlSegment('bid_requests')
      .post({
        data: {
          type: 'bid_requests',
          attributes: { lotId, amount }
        }
      })
  }

  /**
   * Request "buy now" for a lot.
   *
   * @param {string} lotId ID of the lot.
   * @param {string} participantId ID of the participant to request "Buy Now" for.
   *
   * @return {Promise.<JsonApiResponse>}
   */
  requestBuyNow (lotId, participantId) {
    return this
      ._makeLotCallBuilder(lotId)
      .withCredentials()
      .withTimeout(SUBMIT_TRANSACTION_TIMEOUT)
      .appendUrlSegment(['participants', participantId])
      .patch()
  }

  /**
   * Set the winner.
   *
   * @param {string} lotId ID of the lot.
   * @param {string} participantId ID of the winner.
   * @param {boolean} [buyNow=false] Is 'buy now' winner.
   *
   * @return {Promise.<JsonApiResponse>}
   */
  setWinner (lotId, participantId, buyNow = false) {
    return this
      ._makeLotCallBuilder(lotId)
      .withCredentials()
      .withTimeout(SUBMIT_TRANSACTION_TIMEOUT)
      .appendUrlSegment('winners')
      .post({
        data: {
          id: participantId,
          type: 'participants',
          attributes: {
            buyNow
          }
        }
      })
  }

  /**
   * Get lot by ID.
   *
   * @param {string} lotId ID of the lot.
   * @param {object} [query] Request options.
   * @param {object} [query.include] Include resources associated with the lot.
   *
   * @return {JsonApiResponse}
   */
  get (lotId, query) {
    return this
      ._makeLotCallBuilder(lotId)
      .get(query)
  }

  /**
   * Get lots.
   *
   * @param {object} [query] Request options.
   * @param {Number} [query.page.number] Page number.
   * @param {Number} [query.page.size] Page size.
   * @param {string[]} [query.sort] Sorting params.
   * @return {JsonApiResponse}
   */
  getPage (query) {
    return this
      ._makeCallBuilder()
      .get(query)
  }

  /**
   * Get lots count.
   *
   * @param {object} [query] Request options.
   * @return {JsonApiResponse}
   */
  getCount (query) {
    return this
      ._makeCallBuilder()
      .appendUrlSegment('count')
      .get(query)
  }

  /**
   * Get lot participants.
   *
   * @param {object} [query] Request options.
   * @param {Number} [query.page.number] Page number.
   * @param {Number} [query.page.size] Page size.
   * @param {string[]} [query.sort] Sorting params.
   * @return {JsonApiResponse}
   */
  getParticipants (lotId, query) {
    return this
      ._makeLotCallBuilder(lotId)
      .appendUrlSegment('participants')
      .get(query)
  }

  /**
   * Get messages associated with the lot.
   *
   * @param {object} [query] Request options.
   * @param {Number} [query.page.number] Page number.
   * @param {Number} [query.page.size] Page size.
   * @param {string[]} [query.sort] Sorting params.
   * @return {JsonApiResponse}
   */
  getMessages (lotId, query) {
    return this
      ._makeLotCallBuilder(lotId)
      .appendUrlSegment('messages')
      .get(query)
  }

  /**
   * Get the lot participation requests.
   *
   * @param {object} [query] Request options.
   * @param {Number} [query.page.number] Page number.
   * @param {Number} [query.page.size] Page size.
   * @param {string[]} [query.sort] Sorting params.
   * @param {string} [query.requestor] Requestor of the request.
   * @param {reviewer} [query.reviewer] Reviewer of the request.
   * @return {JsonApiResponse}
   */
  getParticipationRequests (lotId, query) {
    return this
      ._makeLotCallBuilder(lotId)
      .appendUrlSegment('participation_requests')
      .get(query)
  }

  /**
   * Get the lot bid requests.
   *
   * @param {object} [query] Request options.
   * @param {Number} [query.page.number] Page number.
   * @param {Number} [query.page.size] Page size.
   * @param {string[]} [query.sort] Sorting params.
   * @param {string} [query.requestor] Requestor of the request.
   * @param {reviewer} [query.reviewer] Reviewer of the request.
   * @return {JsonApiResponse}
   */
  getBidRequests (lotId, query) {
    return this
      ._makeLotCallBuilder(lotId)
      .appendUrlSegment('bid_requests')
      .get(query)
  }

  /**
   * Create a callback request
   * @param {String} lotId - ID of the lot
   * @return {JsonApiResponse}
   */
  createCallback (lotId) {
    return this
      ._makeLotCallBuilder(lotId)
      .appendUrlSegment('callbacks')
      .post()
  }

  /**
   * Set lot winner details
   * @param {String} lotId
   * @param {Object} details
   * @param {String} [details.invoiceId]
   * @param {Boolean} [details.invoicePaid]
   * @param {String} [details.containerId]
   * @param {String} [details.serviceLink]
   * @param {Number} [details.feeAmount]
   * @param {Number} [details.transportationFee]
   * @param {String} [details.feeCurrency]
   * @param {Number} [details.totalAmount]
   */
  setWinnerDetails (lotId, details) {
    return this
      ._makeLotCallBuilder(lotId)
      .appendUrlSegment('winner_details')
      .put({
        data: {
          type: 'winner_details',
          id: lotId,
          attributes: details
        }
      })
  }

  /**
   * Delete a callback request
   * @param {String} lotId - ID of the lot
   * @param {string} [accountId] Account ID of the user.
   * @return {JsonApiResponse}
   */
  deleteCallback (lotId, accountId = null) {
    accountId = safeAccountId(accountId, this._sdk)

    // TODO: add unit tests

    return this
      ._makeLotCallBuilder(lotId)
      .appendUrlSegment(['callbacks', accountId])
      .delete()
  }

  _makeCallBuilder () {
    return this._server
      ._makeCallBuilder()
      .withOptionalCredentials()
      .appendUrlSegment('lots')
  }

  _makeLotCallBuilder (lotId) {
    return this._makeCallBuilder().appendUrlSegment(lotId)
  }
}