<aside> ℹ️ Plug this schema into GraphQL Voyager to visualize all of the relationships. Click “Change Schema”, then SDL, then copy/paste all of the text below into it and click “Display”.

Screenshot 2023-06-29 at 4.12.00 PM.png

</aside>

"Represents a single end user in Siteline. They can only belong to one company."
type User {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  status: UserStatus!
  firstName: String!
  lastName: String!
  email: EmailAddress!
  company: Company!
  jobTitle: String
  phoneNumber: PhoneNumber
}

"Represents a single company in Siteline."
type Company {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  name: String!
  phoneNumber: PhoneNumber
  locations: [Location!]!
  users: [CompanyUser!]!
}

"Represents a single physical location."
type Location {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  nickname: String
  street1: String
  street2: String
  city: String!
  county: String
  state: String!
  country: String!
  postalCode: String
  timeZone: String!
}

"Represents a single user on a single company along with the role of that user."
type CompanyUser {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  user: User!
  company: Company!
  role: CompanyUserRole!
}

"Represents a single project that produces payment applications on a regular schedule."
type Project {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  name: String!
  location: Location!
  timeZone: String!
  projectNumber: String!
  contracts: [Contract!]!
}

"Represents a single contract for a company on a project."
type Contract {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  project: Project!
  billingType: BillingType!
  status: ContractStatus!
  timeZone: String!
  "Not provided if billingType is QUICK"
  sov: Sov
	"Months is an optional parameter, in YYYY-MM-DD format. You can specify multiple months in the array."
  payApps(months: [DateTime!]): [PayApp!]!
  "If this number is set, it will take precedence over the parent Project's projectNumber."
  internalProjectNumber: String
}

"Represents a single (monthly) pay app for a single company on a single project."
type PayApp {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  timeZone: String!
  payAppNumber: SafeInt!

  "Contract that this pay app belongs to"
  contract: Contract!

  """
  Billing type extracted from the contract billing type when pay app is created.
  - For LUMP_SUM/UNIT_PRICE billing, only `progress` items are provided
  - For QUICK billing, only `amountLineItems` are provided, and they all have `type = ADDITIONAL`
  """
  billingType: BillingType!

  """
  A list of progress values for their respective SOV line items.
  Not used for QUICK pay apps.
  This array is empty for all other types of pay apps.
  """
  progress: [SovLineItemProgress!]!

  """
  A list of amount line items for the pay app.
  Only used for QUICK pay apps.
  This array is empty for all other types of pay apps.
  """
  amountLineItems: [AmountLineItem!]! 

  """
  Iff the pay app is in a submitted, synced, or paid state, returns the most recent time it
  was submitted.
  """
  submittedAt: DateTime

  "Used to determine whether the type of pay app is 'normal' or 'retention-only'."
  retentionOnly: Boolean!

  billingStart: DateTime!
  billingEnd: DateTime!

  "Date before which the entire PayApp must be submitted to the GC (external deadline)."
  payAppDueDate: DateTime!

  """
  This is the current amount billed for this PayApp. This includes both retention and stored
  materials.
  """
  currentBilled: SafeInt!

  "This is the current retention for this PayApp."
  currentRetention: SafeInt!

  "This is the total retention held for this PayApp including the current period."
  totalRetention: SafeInt

  "The amount of previous retention billed for this period."
  previousRetentionBilled: SafeInt!

  "Latest status in PayAppStatusLog"
  status: PayAppStatus!

  "Insertion time of the latest status in PayAppStatusLog"
  statusChangedAt: DateTime!

  "Total balance left to finish after this pay app."
  balanceToFinish: SafeInt!

  "The SOV total value as of this pay app"
  totalValue: SafeInt!

  "Retention held percent on the progress billing"
  progressRetentionHeldPercent: Float

  "Retention held percent on the stored materials billing"
  materialsRetentionHeldPercent: Float

  """
  Retention override amount on the pay app on both progress and material billing. Takes precedence
  over the progress and materials percents if set on the pay app. If set, also takes precedence over
  retention values tracked on the individual progresses.
  """
  retentionHeldOverride: SafeInt

  "Total retention being released for this project on this pay app in cents"
  retentionReleased: SafeInt

  "The overall retention held percent as of this payApp"
  retentionHeldPercent: Float!

  "Gets a base set of G702 values to preview for a pay app"
  g702Values: G702Values!
}

type G702Values {
  originalContractSum: SafeInt!
  netChangeByChangeOrders: SafeInt!
  contractSumToDate: SafeInt!
  totalCompletedToDate: SafeInt!
  progressRetentionPercent: Float!
  progressRetentionAmount: SafeInt!
  materialsRetentionPercent: Float!
  materialsRetentionAmount: SafeInt!
  totalRetention: SafeInt!
  totalLessRetainage: SafeInt!
  previousPayments: SafeInt!
  currentPaymentDue: SafeInt!
  balanceToFinish: SafeInt
  balanceToFinishWithRetention: SafeInt
}

"Represents a full schedule of values for a given project and company."
type Sov {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  contract: Contract!
  lineItems: [SovLineItem!]!
  "Sum of totalValue from every SovLineItem. Updated any time the SOV is modified."
  totalValue: SafeInt!
  """
  This includes both retention and stored materials. Stored materials are only ever billed for once,
  and then they're considered a part of totalBilled. It makes sense to split it out in
  SovLineItemProgress as we need to capture that in the specific month.
  """
  totalBilled: SafeInt!
  "This is the total amount of retention that has been accumulated on the entire SOV to date."
  totalRetention: SafeInt!
  """
  A simple helper to share this logic. Runs the formula: (totalBilled / totalValue) to at most 2
  decimal places.
  """
  progressComplete: Float!
  contractNumber: String!
  contractDate: DateTime!
}

"Represents a group of SovLineItems, denoted primarily by a name."
type SovLineItemGroup {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  name: String!
  code: String
  lineItems: [SovLineItem!]!
  sov: Sov!
}

"Represents a single line item from a single SOV."
type SovLineItem {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  sov: Sov!
  "Optional group for this line item"
  sovLineItemGroup: SovLineItemGroup
  sortOrder: SafeInt!
  code: String!
  name: String!
  "This is set to true if this line item is a part of a change order, false otherwise."
  isChangeOrder: Boolean!
  "If this is a change order, this is the date that this SovLineItem was approved."
  changeOrderApprovedDate: DateTime
  "The original total value of the line item when it was added"
  originalTotalValue: SafeInt!
  "The latest total value for the line item"
  latestTotalValue: SafeInt!
  """
  This is the total amount of previously billed stored materials for this line item if the project
  is being added to Siteline part of the way through. This number is independent from previousBilled
  and previousBilled includes both progress and stored materials. For new projects this number is
  set to 0.
  """
  previousStoredMaterials: SafeInt!
  """
  This is the total amount previously billed for this line item if the project is being added to
  Siteline part of the way through. For new projects this number is set to 0.
  """
  previousBilled: SafeInt!
  """
  This includes both retention and stored materials. Stored materials are only ever billed for once,
  and then they're considered a part of totalBilled. It makes sense to split it out in
  SovLineItemProgress as we need to capture that in the specific month. Includes only proposed/paid pay apps.
  """
  totalBilled: SafeInt!
  """
  Equivalent to `totalBilled`, except includes progress billed on draft and signed pay apps as well as
  proposed and paid.
  """
  billedToDate: SafeInt!
  "This is the total amount of retention that has been accumulated on this line item to date."
  totalRetention: SafeInt!
  """
  A simple helper to share this logic. Runs the formula: (totalBilled / totalValue) to at most 2
  decimal places.
  """
  progressComplete: Float!
  progress: [SovLineItemProgress!]!
  "A price per unit, in cents. This is used for UNIT_PRICE contracts."
  unitPrice: SafeInt
  "The human-readable unit of measurement for each unit, e.g. LF, EA, HR for UNIT_PRICE contract."
  unitName: String
  "Retention percent held on the pre-siteline billing"
  preSitelineRetentionHeldPercent: Float
  "Pre-siteline retention override amount in cents. Takes precedence over retention held % if set."
  preSitelineRetentionHeldOverride: SafeInt
  "The computed total amount of retention held pre-siteline in cents."
  preSitelineRetention: SafeInt!
  "Tracks what initial retention % to initialize progress at for the first pay app. Range 0-1."
  defaultRetentionPercent: Float
}

"""
A line item that only contains an amount and a fee.
Used for Quick Billing only.
Current billed = amount * (1 + feePercent)
Eg: "Campbell #A1245, amount $12,345, fee 10%"
Proof of material cost is stored in item attachments.
"""
type AmountLineItem {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  payApp: PayApp!
  type: LineItemType!
  description: String!

  "Current amount billed for this line item"
  amount: SafeInt!

  """
  Fee percentage to apply on top of `currentBilled`.
  For MATERIALS line item types, this is initialized to `contract.materialFeePercent`
  but it can be adjusted manually.
  """
  feePercent: Float!

  "Order in which to display the amount line items. First line item starts at 1."
  sortOrder: SafeInt!
}

"Represents the progress for a single SOV line item, to be used in monthly pay apps."
type SovLineItemProgress {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  sovLineItem: SovLineItem!
  payApp: PayApp!
  """
  This is the current amount billed for a single progress/monthly update. This includes both
  retention and stored material costs. Both of those are tracked separately, in currentRetention
  and in storedMaterialBilled, respectively.
  """
  currentBilled: SafeInt!
  "This is the current progress value"
  progressBilled: SafeInt!
  "This is the current retention on this line item for this single progress/monthly update."
  currentRetention: SafeInt!
  "This is the current stored materials on this line item for this single progress/monthly update."
  storedMaterialBilled: SafeInt!
  "This is the total amount billed in all progress for this line item prior to this pay app."
  previousBilled: SafeInt!
  "This is the total amount billed in all progress for this line item after this pay app."
  futureBilled: SafeInt!
  "This is the total amount of retention in all progress for this line item prior to this pay app."
  previousRetention: SafeInt!
  "The amount of previous retention billed for this period."
  previousRetentionBilled: SafeInt!
  "The line item's total value as of this progress"
  totalValue: SafeInt!
  "The overall retention held percent as of this progress"
  retentionHeldPercent: Float!
  "Retention held percent on the progress billing"
  progressRetentionHeldPercent: Float
  "Retention held percent on the stored materials billing"
  materialsRetentionHeldPercent: Float
  """
  Retention override amount on the sov line item progress on both progress and material billing. Takes
  precedence over the progress and materials percents if set.
  """
  retentionHeldOverride: SafeInt
  "Total retention being released for this line item on this progress in cents"
  retentionReleased: SafeInt
}

"Represents the various roles that could exist at a company."
enum CompanyUserRole {
  "An administrator has all permissions enabled and access to all company projects"
  ADMINISTRATOR
  "Project managers by default see internal project due dates, earlier than GC due dates"
  PROJECT_MANAGER
  "Users with an accountant role see external project due dates by default"
  ACCOUNTANT
}

"Billing type for a project, stored at the contract level."
enum BillingType {
  """
  Project has a fixed Schedule of Values (SOV).
  Pay apps contain progress against each line item in the SOV.
  Total value of the project is fixed and contained within the SOV.
  Retention can be tracked at the project / pay app / standard / progress level.
  """
  LUMP_SUM

  """
  Each pay-app has a free-form list of amount line items.
  Project has no defined total value.
  There is no retention.
  """
  QUICK

  """
  Unit price projects bill monthly pay apps with the same workflow as lump sum projects, but bill
  using unit quantities corresponding to pre-negotiatied unit pricing.
  """
  UNIT_PRICE
}

"The status of a user, right now disabled users do not receive any email notifications."
enum UserStatus {
  ACTIVE
  DISABLED
}

"Represents the overall status of a given contract."
enum ContractStatus {
  "A contract that is not billing right now i.e. because it is put on hold or hasn't started yet."
  INACTIVE
  "A contract that is currently billing and active."
  ACTIVE
  "A contract that has been completed or removed from Siteline."
  ARCHIVED
}

"""
Overarching pay-app status.
State life-cycle with integration:
  DRAFT -> SYNCED -> PAID
State life-cycle with no integration and no notarization needed for their lien waivers:
  DRAFT -> SIGNED -> PROPOSED -> PAID
State life-cycle with no integration but yes notarization needed for their lien waivers:
  DRAFT -> SIGNED -> PROPOSED -> NOTARIZING_UNCONDITIONAL -> PAID
"""
enum PayAppStatus {
  "Pay app has not been signed or submitted yet."
  DRAFT
  "If the pay app is already submitted and the the unconditional lien waiver is being notarized."
  NOTARIZING_UNCONDITIONAL
  "Pay app has been signed and awaiting a final submit to the General Contractor."
  SIGNED
  """
  The user has clicked Sync but its still pending because the draw isn't open yet. This is
  considered the same as a synced state in that if a user edits anything, the pay app state will
  revert to draft and the pending sync will be canceled.
  """
  SYNC_PENDING
  "Pay app has been synced (i.e. to Textura)."
  SYNCED
  "Pay app sync has failed. If a user modifies the pay app, it will revert to draft state."
  SYNC_FAILED
  "Pay app has been submitted for full-review to the General Contractor."
  PROPOSED
  "Pay app has been paid out by the GC and the unconditional lien waiver has been signed."
  PAID
}

"""
Type of a Rate or Amount line item.
This is used to determine grouping in T&M invoices, but can also be used to aggregate and categorize
different types of line items in pay-app packages.
"""
enum LineItemType {
  LABOR
  MATERIALS
  ADDITIONAL
}

type Query {
  currentCompany: Company!
	contracts: [Contract!]!
	contract(id: ID!): Contract!
	payApp(id: ID!): PayApp!
}

scalar SafeInt
scalar DateTime
scalar EmailAddress
scalar PhoneNumber
scalar URL
scalar Upload
scalar JSONObject
scalar LatLng