Skip to main content

개요

Folio 도메인은 숙박 시설에서 고객의 계정 및 그룹 단위 청구를 관리하는 시스템입니다. Folio는 예약(Reservation)과 비즈니스 블록(BusinessBlock)을 묶어 통합 청구를 제공하며, 요금제(RatePlan) 및 포함 항목(Inclusion) 스냅샷을 관리합니다.

주요 기능

  • Folio 생성 및 관리: 고객 계정 또는 그룹 단위 Folio 생성
  • 예약 연결: 기존 Folio에 예약 추가
  • 비즈니스 블록 연결: 기존 Folio에 비즈니스 블록 추가
  • 요금 스냅샷 관리: 적용된 요금제 및 포함 항목 추적
  • 청구서 연동: Folio 내 모든 청구서(Bill) 통합 관리

Queries

getFolio

특정 Folio의 상세 정보를 조회합니다.

GraphQL Signature

query GetFolio($id: ID!) {
  getFolio(id: $id) {
    id
    folioCode
    name
    status
    accommodationId
    accountProfileId
    groupProfileId
    accountProfile {
      id
      name
    }
    groupProfile {
      id
      name
    }
    bills {
      id
      billCode
      totalAmount
      balanceAmount
    }
    appliedFolioRates {
      id
      totalAmount
      balanceAmount
    }
    appliedFolioInclusions {
      id
      totalAmount
      balanceAmount
    }
    reservations {
      id
      reservationCode
    }
    businessBlocks {
      id
      blockCode
    }
    createdAt
    updatedAt
  }
}

파라미터

id
ID!
required
조회할 Folio의 고유 식별자

응답

id
ID!
Folio의 고유 식별자 (ULID 형식)
folioCode
String!
Folio의 고유 코드 (자동 생성)
name
String
Folio 이름 (선택사항)
status
FolioStatus!
Folio 상태:
  • ACTIVE: 활성
  • CLOSED: 종료
accommodationId
ID!
숙박 시설 ID
accountProfile
Profile
계정 프로필 정보
groupProfile
Profile
그룹 프로필 정보
bills
[Bill!]!
Folio에 속한 청구서 목록
appliedFolioRates
[FolioRateSnapshot!]!
적용된 요금제 스냅샷 목록
appliedFolioInclusions
[FolioInclusionSnapshot!]!
적용된 포함 항목 스냅샷 목록
reservations
[Reservation!]!
연결된 예약 목록
businessBlocks
[BusinessBlock!]!
연결된 비즈니스 블록 목록
transferredFolioRates
[TransferredRate!]!
다른 Folio로 이전된 요금 스냅샷
transferredFolioInclusions
[TransferredInclusion!]!
다른 Folio로 이전된 포함 항목 스냅샷

예제

query {
  getFolio(id: "01HQKS9V8X2N3P4Q5R6S7T8U9V") {
    id
    folioCode
    name
    status
    accountProfile {
      name
    }
    bills {
      billCode
      totalAmount
    }
  }
}

getFolios

숙박 시설의 Folio 목록을 필터링하여 조회합니다.

GraphQL Signature

query GetFolios(
  $accommodationId: ID!
  $filter: FolioFilterInput
  $orders: [OrderInput!]
  $first: Int
  $after: String
) {
  getFolios(
    accommodationId: $accommodationId
    filter: $filter
    orders: $orders
    first: $first
    after: $after
  ) {
    edges {
      node {
        id
        folioCode
        name
        status
        createdAt
      }
      cursor
    }
    pageInfo {
      hasNextPage
      endCursor
    }
    totalCount
  }
}

파라미터

accommodationId
ID!
required
숙박 시설 ID
filter
FolioFilterInput
필터 조건:
  • name: Folio 이름 검색 (부분 일치)
  • startDate: 생성일 시작 범위
  • endDate: 생성일 종료 범위
  • status: Folio 상태 필터
  • accountProfileIds: 계정 프로필 ID 목록
  • groupProfileIds: 그룹 프로필 ID 목록
orders
[OrderInput!]
정렬 조건 (예: [{ field: "createdAt", direction: DESC }])
first
Int
페이지당 항목 수 (기본값: 10)
after
String
페이지네이션 커서

응답

페이지네이션된 Folio 목록을 반환합니다 (Relay-style Cursor Connection).

예제

query {
  getFolios(
    accommodationId: "01HQKS9V8X2N3P4Q5R6S7T8U9V"
    filter: {
      status: ACTIVE
      startDate: "2025-01-01T00:00:00Z"
    }
    orders: [{ field: "createdAt", direction: DESC }]
    first: 20
  ) {
    edges {
      node {
        id
        folioCode
        name
        status
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
    totalCount
  }
}

Mutations

createFolio

새로운 Folio를 생성합니다. Folio는 독립적으로 생성되며, 예약 및 비즈니스 블록은 별도로 추가해야 합니다.

GraphQL Signature

mutation CreateFolio($input: CreateFolioInput!) {
  createFolio(input: $input) {
    id
    folioCode
    name
    status
    accommodationId
    accountProfileId
    groupProfileId
    createdAt
  }
}

파라미터

input.accommodationId
ID!
required
숙박 시설 ID
input.accountProfileId
ID
계정 프로필 ID (선택사항)
input.groupProfileId
ID
그룹 프로필 ID (선택사항)
input.name
String
Folio 이름 (선택사항)
input.folioRatePlans
[FolioRatePlanInput!]
적용할 요금제 목록:
  • ratePlanId: 요금제 ID
  • rateId: 요금 ID
  • quantity: 수량
  • startDate: 시작일
  • endDate: 종료일
input.folioInclusions
[FolioInclusionInput!]
적용할 포함 항목 목록:
  • inclusionId: 포함 항목 ID
  • quantity: 수량
  • usageDate: 사용 날짜

응답

생성된 Folio 객체를 반환합니다.

예제

mutation {
  createFolio(
    input: {
      accommodationId: "01HQKS9V8X2N3P4Q5R6S7T8U9V"
      name: "김철수 님 단체 예약"
      accountProfileId: "01HQKS9V8X2N3P4Q5R6S7T8U9W"
      folioRatePlans: [
        {
          ratePlanId: "01HQKS9V8X2N3P4Q5R6S7T8U9X"
          rateId: "01HQKS9V8X2N3P4Q5R6S7T8U9Y"
          quantity: 2
          startDate: "2025-12-23"
          endDate: "2025-12-25"
        }
      ]
    }
  ) {
    id
    folioCode
    name
    status
  }
}
Folio 생성 시 요금제와 포함 항목을 지정하면 자동으로 청구서(Bill)가 생성됩니다.

updateFolio

기존 Folio의 정보를 수정합니다.

GraphQL Signature

mutation UpdateFolio($input: UpdateFolioInput!) {
  updateFolio(input: $input) {
    id
    folioCode
    name
    status
    updatedAt
  }
}

파라미터

input.id
ID!
required
수정할 Folio의 ID
input.name
String
변경할 Folio 이름
input.status
FolioStatus
변경할 Folio 상태 (ACTIVE | CLOSED)
input.accountProfileId
ID
변경할 계정 프로필 ID
input.groupProfileId
ID
변경할 그룹 프로필 ID

응답

수정된 Folio 객체를 반환합니다.

예제

mutation {
  updateFolio(
    input: {
      id: "01HQKS9V8X2N3P4Q5R6S7T8U9Z"
      name: "김철수 님 VIP 단체 예약"
      status: CLOSED
    }
  ) {
    id
    folioCode
    name
    status
  }
}

deleteFolio

Folio를 삭제합니다.

GraphQL Signature

mutation DeleteFolio($id: ID!) {
  deleteFolio(id: $id)
}

파라미터

id
ID!
required
삭제할 Folio의 ID

응답

success
Boolean!
삭제 성공 여부 (true 반환)

예제

mutation {
  deleteFolio(id: "01HQKS9V8X2N3P4Q5R6S7T8U9Z")
}
Folio 삭제 시 연결된 예약, 청구서, 결제 정보도 함께 영향을 받을 수 있습니다. 삭제 전 데이터를 확인하세요.

addReservationToFolio

기존 Folio에 새로운 예약을 추가합니다.

GraphQL Signature

mutation AddReservationToFolio($input: AddReservationToFolioInput!) {
  addReservationToFolio(input: $input) {
    id
    reservationCode
    folioId
    checkInDate
    checkOutDate
    status
  }
}

파라미터

input.folioId
ID!
required
예약을 추가할 Folio ID
input.businessBlockId
ID
연결할 비즈니스 블록 ID (선택사항)
input.profileIds
[ID!]
예약에 연결할 프로필 ID 목록
input.checkInDate
Date!
required
체크인 날짜
input.checkOutDate
Date!
required
체크아웃 날짜
input.roomTypeId
ID!
required
객실 타입 ID
input.ratePlans
[RatePlanInput!]
적용할 요금제 목록
input.inclusions
[InclusionInput!]
적용할 포함 항목 목록
input.needCheckIn
Boolean
즉시 체크인 처리 여부 (기본값: false)
input.sendSMS
Boolean
예약 확인 SMS 발송 여부 (기본값: false)

응답

생성된 Reservation 객체를 반환합니다.

예제

mutation {
  addReservationToFolio(
    input: {
      folioId: "01HQKS9V8X2N3P4Q5R6S7T8U9Z"
      checkInDate: "2025-12-23"
      checkOutDate: "2025-12-25"
      roomTypeId: "01HQKS9V8X2N3P4Q5R6S7T8U9A"
      profileIds: ["01HQKS9V8X2N3P4Q5R6S7T8U9B"]
      needCheckIn: false
      sendSMS: true
    }
  ) {
    id
    reservationCode
    folioId
    checkInDate
    checkOutDate
    status
  }
}
needCheckIn을 true로 설정하면 예약 생성과 동시에 체크인 처리됩니다.

addBusinessBlockToFolio

기존 Folio에 새로운 비즈니스 블록을 추가합니다.

GraphQL Signature

mutation AddBusinessBlockToFolio($input: AddBusinessBlockToFolioInput!) {
  addBusinessBlockToFolio(input: $input) {
    id
    blockCode
    folioId
    blockName
    startDate
    endDate
    status
  }
}

파라미터

input.folioId
ID!
required
비즈니스 블록을 추가할 Folio ID
input.blockName
String!
required
블록 이름
input.startDate
Date!
required
블록 시작 날짜
input.endDate
Date!
required
블록 종료 날짜
input.roomTypeId
ID!
required
객실 타입 ID
input.roomCount
Int!
required
예약할 객실 수

응답

생성된 BusinessBlock 객체를 반환합니다.

예제

mutation {
  addBusinessBlockToFolio(
    input: {
      folioId: "01HQKS9V8X2N3P4Q5R6S7T8U9Z"
      blockName: "연말 세미나 블록"
      startDate: "2025-12-23"
      endDate: "2025-12-25"
      roomTypeId: "01HQKS9V8X2N3P4Q5R6S7T8U9A"
      roomCount: 10
    }
  ) {
    id
    blockCode
    folioId
    blockName
    startDate
    endDate
    status
  }
}

데이터 모델

FolioStatus

Folio의 상태를 나타냅니다.
  • ACTIVE: 활성 상태 (청구 및 예약 가능)
  • CLOSED: 종료 상태 (정산 완료)

FolioRateSnapshot

Folio에 적용된 요금제의 스냅샷입니다. 요금제 변경 시에도 기존 스냅샷은 유지됩니다. 주요 필드:
  • appliedRatePlan: 적용된 요금제 정보 (히스토리)
  • appliedRate: 적용된 요금 정보 (히스토리)
  • totalAmount: 총 요금
  • balanceAmount: 잔액
  • businessBlock: 연결된 비즈니스 블록

FolioInclusionSnapshot

Folio에 적용된 포함 항목의 스냅샷입니다. 주요 필드:
  • appliedInclusion: 적용된 포함 항목 정보 (히스토리)
  • totalAmount: 총 금액
  • balanceAmount: 잔액

에러 처리

DATA_NOT_FOUND_ON_ID
지정한 ID의 Folio를 찾을 수 없습니다.
BUSINESS_BLOCK_FOLIO_MISMATCH
비즈니스 블록이 지정한 Folio에 속하지 않습니다.
REQUIRED_PARAMETER
필수 파라미터가 누락되었습니다.
INVALID_PARAMETER
잘못된 파라미터가 전달되었습니다.

사용 흐름

  1. Folio 생성: createFolio로 계정 또는 그룹 단위 Folio 생성
  2. 예약 추가: addReservationToFolio로 Folio에 예약 연결
  3. 비즈니스 블록 추가: addBusinessBlockToFolio로 단체 블록 연결
  4. 청구서 확인: Folio에 자동 생성된 청구서 조회
  5. Folio 종료: 정산 완료 후 updateFolio로 상태를 CLOSED로 변경

관련 API