Работа с датами NetSuite во Freemarker - PullRequest
2 голосов
/ 20 мая 2019

Я пытался добавить столбец «Открытые дни» и «Просроченные дни» в расширенный шаблон PDF для выписок в NetSuite.Однако я продолжаю сталкиваться с проблемами при обработке значений дат, полученных из записей NetSuite.Попытки манипулировать значениями даты продолжают приводить к неопределенным ошибкам.Я немного сбит с толку относительно того, могу ли я даже заставить эту работу сейчас.

Например, если я применяю следующее к шаблону, он работает для форматирования любых значений даты и даты / времени, введенных вшаблон:

<#setting date_format="dd-MM-yyyy">
<#setting datetime_format="dd-MM-yyyy hh:mm a">

Однако, если я пытаюсь работать со значениями как объекты даты / даты и времени, это приводит к ошибкам.Так что попытка сделать что-то вроде следующего не удалась:

<#assign d2 = line.duedate?long>

Пока это работает:

<#assign d1 = .now?date?long>

Также, пытаясь предположить, что значение на самом деле является строкой, переданной и преобразованной вdate / datetime также не работает.Выполнение следующих действий приводит к ошибке:

<#assign d2 = line.datecol?date("M/d/yyyy")> // format used by default in NetSuite date output

Другая вещь, которая не имела смысла, - это проверка по дате исполнения и отображение значения только при наличии даты исполнения (защита от отображения данных для записей выписки, которые былина самом деле не счета).Таким образом, даже если срок исполнения был установлен и отображен в заполненном PDF, следующее не смогло показать правильные результаты:

<#if line.duedate?has_content>${daysoverdue}<#else>empty</#if>

Вместо того, чтобы показывать, что было бы просроченным значением (в настоящее время просто статическое значениедля тестирования) будет отображаться «пусто».Независимо от того, было ли доступно значение срока оплаты, весь столбец для каждой строки отображался бы так, как если бы поле было пустым.Так что, я не знаю, связано это или нет.

Я долго этим занимался, и до сих пор не нашел ничего полезного в поиске.

1 Ответ

3 голосов
/ 20 мая 2019

Здесь происходит несколько вещей:

  1. line.duedate не всегда имеет допустимое значение даты - IE: когда строка является кредитовым авизо, дата оплаты не применяется.В этом случае попытка присвоить line.duedate?long переменной приведет к ошибке.Чтобы избежать этого, вы можете сначала проверить, что он действителен.
  2. Однако использование ?has_content не работает для этого, как вы ожидаете.Трудно точно определить, почему это так, но есть ключ к пониманию того, почему это может быть в документации Freemarker (выделение добавлено):

has_content

Это правда, если переменная существует (и не является Java нулевой) и не является "пустой", в противном случае она ложна.Значение «пусто» зависит от конкретного случая.Это следует из интуитивных идей здравого смысла.Следующие значения являются пустыми: строка с длиной 0, выходное значение разметки с разметкой длины 0, последовательность или хэш без суб-переменных, коллекция, которая прошла последний элемент.Если значение не относится ни к одному из этих типов, оно считается непустым, если это число, дата или логическое значение (например, 0 и false не пустые), в противном случае оно считается пустым. Обратите внимание, что, когда ваша модель данных реализует несколько интерфейсов шаблонной модели, вы можете получить неожиданные результаты. Однако, если вы сомневаетесь, вы можете использовать всегда использовать expr!? Size> 0 или expr!? Length> 0 вместо expr? has_content.

Это встраивание является исключительным в том смысле, что вы можете использовать трюк со скобками, как с оператором значения по умолчанию.То есть вы можете написать как product.color? Has_content, так и (product.color) has_content.Первое не относится к случаю, когда товар отсутствует, последнее делает.

line.datecol?date("M/d/yyyy") не будет работать, так как datecol, подобно duedate, распознается Freemarker как date_like - не строка.Там, где пусто, duedate распознается как строка, но, конечно, не соответствует формату, будучи пустым. daysoverdue, по-видимому, недоступно в модели данных для оператора,Однако это может быть рассчитано.

Чтобы свести воедино все эти точки, вы можете сначала проверить, верна ли дата оплаты, а затем рассчитать просроченные дни:

<#if line.duedate?is_date_like>
  <#assign d2 = line.duedate?long>
  <#assign daysoverdue = ((.now?date?long - d2) / (24*60*60*1000))?floor>
<#else>
  <#assign d2 = "">
  <#assign daysoverdue = "">
</#if>

Затем вы можете использовать ${daysoverdue}в одной из ваших колонн.Вы можете выполнить аналогичный процесс для расчета и отображения открытых дней.

...