code: protected function resolveOutstandingDate(SaleInterface $sale)
      {
          if (!$sale instanceof InvoiceSubjectInterface) {
              return null;
          }
          if (!$sale instanceof ShipmentSubjectInterface) {
              return null;
          }
  
          if (null === $term = $sale->getPaymentTerm()) {
              return null;
          }
  
          if (!$this->saleHasOutstandingPayments($sale)) {
              return null;
          }
  
          $from = null;
          switch ($term->getTrigger()) {
              case PaymentTermTriggers::TRIGGER_SHIPPED:
                  $from = $sale->getShippedAt();
                  break;
  
              case PaymentTermTriggers::TRIGGER_FULLY_SHIPPED:
                  if ($sale->getShipmentState() === ShipmentStates::STATE_COMPLETED) {
                      $from = $sale->getShippedAt(true);
                  }
                  break;
  
              case PaymentTermTriggers::TRIGGER_INVOICED:
                  $from = $sale->getInvoicedAt();
                  break;
  
              case PaymentTermTriggers::TRIGGER_FULLY_INVOICED:
                  if ($sale->getInvoiceState() === InvoiceStates::STATE_COMPLETED) {
                      $from = $sale->getInvoicedAt(true);
                  }
                  break;
          }
  
          if (null === $from) {
              return null;
          }
  
          // Calculate outstanding date
          $date = clone $from;
          $date->setTime(23, 59, 59);
          $date->modify(sprintf('+%s days', $term->getDays()));
          if ($term->getEndOfMonth()) {
              $date->modify('last day of this month');
          }
  
          return $date;
      }
docs: Resolves the outstanding date.
  
  @param SaleInterface $sale
  
  @return \DateTime|null