# * forecast tests
# Test generation of periodic transactions with --forecast.
# Note periodic transaction tests should include a regular transaction
# to pin the start date of forecasted transactions.

<
2016/12/31
    expenses:housing  $600
    assets:cash

~ monthly from 2016/1
    income  $-1000
    expenses:food     $20
    expenses:leisure  $15
    expenses:grocery  $30
    assets:cash

# ** 1. A balance report with forecasted transactions.
$ hledger bal -M -b 2016-11 -e 2017-02 -f - --forecast
Balance changes in 2016-11-01..2017-01-31:

                  || 2016-11  2016-12  2017-01 
==================++===========================
 assets:cash      ||       0    $-600     $935 
 expenses:food    ||       0        0      $20 
 expenses:grocery ||       0        0      $30 
 expenses:housing ||       0     $600        0 
 expenses:leisure ||       0        0      $15 
 income           ||       0        0   $-1000 
------------------++---------------------------
                  ||       0        0        0 
>=0

<
2016/12/31
    expenses:housing  $600
    assets:cash

~ monthly from 2016/1  * marked cleared, and with a description
    income  $-1000
    expenses:food     $20
    expenses:leisure  $15
    expenses:grocery  $30
    assets:cash

# ** 2. print forecasted transactions, with status and description.
$ hledger print -b 2016-11 -e 2017-02 -f - --forecast
2016-12-31
    expenses:housing            $600
    assets:cash

2017-01-01 * marked cleared, and with a description
    income                    $-1000
    expenses:food                $20
    expenses:leisure             $15
    expenses:grocery             $30
    assets:cash

>=0

<
2016/12/31
    expenses:housing  $600
    assets:cash

~ monthly from 2016/1  ; or a comment, maybe with a:tag
    income  $-1000
    expenses:food     $20
    expenses:leisure  $15
    expenses:grocery  $30
    assets:cash

# ** 3. A register with forecasted transactions, with a comment and tag.
$ hledger register -b 2016-11 -e 2017-02 -f - --forecast  tag:a
2017-01-01                      income                      $-1000        $-1000
                                expenses:food                  $20         $-980
                                expenses:leisure               $15         $-965
                                expenses:grocery               $30         $-935
                                assets:cash                   $935             0
>=0

<
2016/01/01
    expenses:fun  $10 ; more fireworks
    assets:cash

2016/12/02
    expenses:housing  $600
    assets:cash

~ yearly from 2016
    income  $-10000 ; bonus
    assets:cash

# ** 4. Check that --forecast generates transactions only after last transaction date in journal.
$ hledger register -b 2015-12 -e 2017-02 -f - assets:cash --forecast
2016-01-01                      assets:cash                   $-10          $-10
2016-12-02                      assets:cash                  $-600         $-610
2017-01-01                      assets:cash                 $10000         $9390
>=0

<
Y 2000

~ 2/1  forecast

; a real transaction to set the start of the forecast window
2000/1/1 real

# ** 5. Y affects M/D partial dates in periodic transactions.
# The recur tag shows the original period expression and is not modified.
# Also the --verbose-tags flag adds a visible tag.
$ hledger -f - print --forecast desc:forecast --verbose-tag
2000-02-01 forecast
    ; generated-transaction: ~ 2/1

>=0

<
Y 2000

~ 15  forecast

; a real transaction to set the start of the forecast window
2000/1/1 real

# ** 6. Y also sets the month to 1, affecting D dates:
$ hledger -f - print --forecast desc:forecast
2000-01-15 forecast

>=0

<
Y 2000

~ next month  forecast

; a real transaction to set the start of the forecast window
2000/1/1 real

# ** 7. Y also sets the day to 1, affecting relative dates:
$ hledger -f - print --forecast desc:forecast
2000-02-01 forecast

>=0


<
2016/12/31
    expenses:housing  $600
    assets:cash

~ monthly from 2016/1  salary
    income  $-1000
    assets:cash

# ** 8. A balance report with forecast-begin enabling transaction before report end
$ hledger bal -M -b 2016-10 -e 2017-02 -f - --forecast=20160801-
Balance changes in 2016-10-01..2017-01-31:

                  || 2016-10  2016-11  2016-12  2017-01 
==================++====================================
 assets:cash      ||   $1000    $1000     $400    $1000 
 expenses:housing ||       0        0     $600        0 
 income           ||  $-1000   $-1000   $-1000   $-1000 
------------------++------------------------------------
                  ||       0        0        0        0 
>=0

# ** 9. Parse error in malformed forecast period expression
$ hledger bal -M -b 2016-10 -e 2017-02 -f - --forecast=20160801-foobar
>
>2
hledger: Error: could not parse forecast period : 1:10:
  |
1 | 20160801-foobar
  |          ^
unexpected 'f'
expecting end of input
 (use -h to see usage)
>=1

<
commodity 1,000.00 USD

2020-01-01
  (a)      1,000.00 USD

~ every 28th day
  (a)       1000.00 USD

# ** 10. Amount display style is applied to forecasted transactions.
$ hledger -f - reg --forecast date:202001
2020-01-01                      (a)                   1,000.00 USD  1,000.00 USD
2020-01-28                      (a)                   1,000.00 USD  2,000.00 USD
>=0

<
2021-09-01  Normal Balance Assertion Works
    Checking   = -60
    Costs

~ 2021-10-01  explicit forecasted assertion
    Checking      = -100
    Costs             40

~ 2021-10-02  auto-deduced forecasted assertion
    Checking      = -120
    Costs

# ** 11. Forecast transactions work with balance assignments
$ hledger -f - print -x --forecast -e 2021-11 --verbose-tags
2021-09-01 Normal Balance Assertion Works
    Checking             -60 = -60
    Costs                 60

2021-10-01 explicit forecasted assertion
    ; generated-transaction: ~ 2021-10-01
    Checking             -40 = -100
    Costs                 40

2021-10-02 auto-deduced forecasted assertion
    ; generated-transaction: ~ 2021-10-02
    Checking             -20 = -120
    Costs                 20

>=0

<
2021-08-01
  (a)      0

~ every weekday
  income:client1                    -10 USD
  assets:receivables:contractor1

# ** 12. Generated forecast for weekday transactions
$ hledger -f - reg --forecast -b "2021-09-01" -e "2021-09-15" --forecast -w 100
2021-09-01                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
2021-09-02                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
2021-09-03                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
2021-09-06                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
2021-09-07                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
2021-09-08                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
2021-09-09                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
2021-09-10                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
2021-09-13                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
2021-09-14                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
>=0

<
2021-08-01
  (a)      0

~ every weekendday
  income:client1                    -10 USD
  assets:receivables:contractor1

# ** 13. Generated forecast for weekend transactions
$ hledger -f - reg --forecast -b "2021-09-01" -e "2021-09-15" --forecast -w 100
2021-09-04                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
2021-09-05                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
2021-09-11                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
2021-09-12                                income:client1                       -10 USD       -10 USD
                                          assets:receivables:contractor1        10 USD             0
>=0

<
2021-01-01
  (a)      1000

~ daily
  (a)       1

# ** 14. Arguments to --forecast take precedence over anything. Only generate up to the day before the end date.
$ hledger -f - reg --forecast="2020-01-01..2020-01-05" -b 2019-12-01 -e 2020-02-01 -H
2020-01-01                      (a)                              1             1
2020-01-02                      (a)                              1             2
2020-01-03                      (a)                              1             3
2020-01-04                      (a)                              1             4
>=0

# ** 15. With no arguments to --forecast, we use the report start date if it's after the journal end date.
$ hledger -f - reg --forecast -b 2021-02-01 -e 2021-02-05 -H
2021-02-01                      (a)                              1          1001
2021-02-02                      (a)                              1          1002
2021-02-03                      (a)                              1          1003
2021-02-04                      (a)                              1          1004
>=0

# ** 16. With no arguments to --forecast, we use journal end date if it's after the report start date.
$ hledger -f - reg --forecast -b 2020-12-01 -e 2021-01-05 -H
2021-01-01                      (a)                           1000          1000
2021-01-02                      (a)                              1          1001
2021-01-03                      (a)                              1          1002
2021-01-04                      (a)                              1          1003
>=0

# ** 17. With no arguments to --forecast, and no report start, generate from journal end to 180 days from today.
# We use here the fact that we are at least 180 days from 2021-01-01. This test will fail if you travel back in time!
$ hledger -f - reg --forecast -H
> /1          1360/
>=0

<
~ daily
  (a)       1

# ** 18. No real transactions.
# Arguments to --forecast take precedence over anything. Only generate up to the day before the end date.
$ hledger -f - reg --forecast="2020-01-01..2020-01-05" -b 2019-12-01 -e 2020-01-05 -H
2020-01-01                      (a)                              1             1
2020-01-02                      (a)                              1             2
2020-01-03                      (a)                              1             3
2020-01-04                      (a)                              1             4
>=0

# ** 19. No real transactions.
# With no arguments to --forecast, we use the report start date.
$ hledger -f - reg --forecast -b 2021-02-01 -e 2021-02-05 -H
2021-02-01                      (a)                              1             1
2021-02-02                      (a)                              1             2
2021-02-03                      (a)                              1             3
2021-02-04                      (a)                              1             4
>=0

# ** 20. No real transactions.
# With no arguments to --forecast, and no report start, generate from today to 180 days from today.
$ hledger -f - reg --forecast -H
> /1           180/
>=0

# ** 21. Only today's date (or a Y year declaration) affects relative dates;
# an explicit report period or forecast period does not. (#1845)
# More explanation:
# - "next quarter" is a relative date meaning "next quarter after the 1st of the current year" (a bug, see 21b).
# - Current year is 2021 (because --today sets the current day to be in 2021, for a repeatable test). 
# - Neither the start or end year of the report or forecast periods (2020, 2022) are used.
<
~ quarterly from next quarter
  (a)  1
$ hledger -f- --today=2021-05-01 reg --period=2020-2022 --forecast=2020-2022
2021-04-01                      (a)                              1             1
2021-07-01                      (a)                              1             2
2021-10-01                      (a)                              1             3
>=0

# # ** 21b. Only a Y year declaration, or today's date, affects relative dates;
# the report period or forecast period do not (#1845).
# Also, without Y, relative dates should be relative to "today" (#1843, #1849). 
# Explanation of the below: "next quarter" is a relative date. 
# There's no Y, so it's relative to "today", which here is set to 2021-05-01
# with --today for repeatability. The "recurrence period" begins with the first
# quarter after that, ie 2021-07-01.  The report and forecast periods' 
# start/end dates (2020, 2022) do not affect the relative date.
# <
# ~ quarterly from next quarter
#   (a)  1
# $ hledger -f- --today=2021-05-01 reg --period=2020-2022 --forecast=2020-2022
# 2021-07-01                      (a)                              1             2
# 2021-10-01                      (a)                              1             3
# >=0

# ** 22. Printed JSON with forecast transactions reference periodic transactions source position
<
~ 2023-01-01   Forecasted
    A      -1
    B       1

$ hledger -f- print --forecast=2023 -O json
> /.*
        "sourceColumn": 1,
        "sourceLine": 1,
        "sourceName": "-"
      },
      {
        "sourceColumn": 1,
        "sourceLine": 4,
        "sourceName": "-"
.*/

# ** 23. Every nth day of month dates near end of month are calculated correctly
# regardless of forecast start date. (#2032)
<
~ every 31st day of month
    (a)  1

$ hledger -f- reg --forecast=2023-03-30..2023-10
2023-03-31                      (a)                              1             1
2023-04-30                      (a)                              1             2
2023-05-31                      (a)                              1             3
2023-06-30                      (a)                              1             4
2023-07-31                      (a)                              1             5
2023-08-31                      (a)                              1             6
2023-09-30                      (a)                              1             7
