def splitInvoiceItemIntoPublications()

in src/main/scala/com/gu/invoicing/preview/Impl.scala [225:270]


  def splitInvoiceItemIntoPublications(
      invoiceItem: InvoiceItem,
  ): List[Publication] = {

    @tailrec def loop(
        currentStart: LocalDate,
        endDateInclusive: LocalDate,
        day: DayOfWeek,
        publications: List[Publication],
    ): List[Publication] = {
      if (currentStart.isAfter(endDateInclusive)) {
        publications
      } else {
        loop(
          currentStart `with` next(day),
          endDateInclusive,
          day,
          Publication(
            publicationDate = currentStart,
            invoiceDate = invoiceItem.serviceStartDate,
            nextInvoiceDate = invoiceItem.serviceEndDate.plusDays(1),
            invoiceItem.productName,
            invoiceItem.chargeName,
            chargeNameToDay(invoiceItem),
            pricePerPublication(invoiceItem),
            invoiceItem.id,
          ) :: publications,
        )
      }
    }

    // This is needed because first publication date might not fall exactly on serviceStartDate
    val publicationDayOfWeek = chargeNameToDay(invoiceItem)
    val firstPublicationDateInPeriod =
      if (invoiceItem.serviceStartDate.getDayOfWeek == publicationDayOfWeek)
        invoiceItem.serviceStartDate
      else
        invoiceItem.serviceStartDate `with` next(publicationDayOfWeek)

    loop(
      firstPublicationDateInPeriod,
      invoiceItem.serviceEndDate,
      publicationDayOfWeek,
      Nil,
    )
  }