oops, old email....

On Mon, Feb 26, 2024 at 10:54 AM CD <[email protected]> wrote:

> You wrote...
>
> "First comment; the code
>    withdrawal_amount % 2 != 0"
>
> How about... fee_amount = withdrawal_amount % 10...
>

that's probably a good heuristic within the US, i don't think many ATMs
dispense denominations less than 10USD, and I don't think I've ever seen
one that charges as much as 10USD in fees.

Might not work if you're traveling overseas and withdrawing in a foreign
currency....


>
> I almost have a working script.  I'll post the completed one up shortly.
> On Monday, February 26, 2024 at 12:22:51 PM UTC-5 [email protected]
> wrote:
>
>> First comment; the code
>>    withdrawal_amount % 2 != 0
>>
>> checks for "evenness" in the sense of odd (1, 3, 5) vs even (2, 4, 6)
>> numbers.   This doesn't seem like what you'd want, since if your fee were
>> $5 and you withdraw $100, it would count it one way, but if the fee were $2
>> it would count it the other.  Only you can come up with the best heuristic
>> for yourself (based on your typical withdrawal amounts and typical fees)
>> but you might want to revisit this one.
>>
>>
>> as for not appending the posting, it's a bit hard to figure out from your
>> two code snippets since I can't tell where the 2nd code snippet lives in
>> relation to the 1st.  But I suspect that in the 2nd snippet, the "txn"
>> you're adding the postings to is not the one you expect.  If the 2nd
>> snippet actually lives in the context of the
>>                 if "ATM" in description:
>> condition in the first snippet, then you're adding to "txn" before you
>> create the txn for this input.  That means you're probably adding it to the
>> txn from the previous iteration, which is still visible and accessible
>> (thanks, Python).
>>
>> On Mon, Feb 26, 2024 at 7:11 AM CDT <[email protected]> wrote:
>>
>>> I don't like to carry much cash when I travel for business, so from time
>>> to time I use my ATM card at a machine when I'm away and it charges a fee
>>> that is included in the total.
>>>
>>> ie - I get $500 cash but the full amount shows as one transaction of
>>> $507.99 (the fee isn't separated)
>>>
>>> I am trying to figure out a way to have this separated out when I use an
>>> Importer so that it would show up as $500 USD in cash and 7.99 USD in fees
>>>
>>> I have a working CSV import for my PNC transactions, but I can't seem to
>>> figure out how to include this.
>>>
>>> Here's the code I use at them moment (without the fees)...
>>>
>>> from beancount.ingest.importer import ImporterProtocol
>>> from beancount.core import data
>>> from beancount.core import amount
>>> from beancount.core.number import D
>>> from dateutil.parser import parse
>>> import datetime
>>> import csv
>>> import re
>>> import logging
>>> import warnings
>>> from beancount.core import flags
>>>
>>> class PNCChecking(ImporterProtocol):
>>>     def __init__(self, account, currency="USD"):
>>>         self.account = account
>>>         self.currency = currency
>>>         super().__init__()
>>>
>>>     def identify(self, file):
>>>         # Check if the file name contains "pnc checking" and ends with
>>> ".csv"
>>>         if "pnc checking" in file.name.lower() and file
>>> .name.lower().endswith('.csv'):
>>>             return True
>>>         else:
>>>             return False
>>>
>>>     def file_account(self, file):
>>>         return self.account
>>>
>>>     def extract(self, file):
>>>         entries = []
>>>
>>>         with open(file.name) as infile:
>>>             reader = csv.reader(infile)
>>>             next(reader, None)  # Skip the header row
>>>
>>>             for index, row in enumerate(reader):
>>>                 if len(row) < 5:  # Checking if the row has at least 5
>>> elements
>>>                     logging.warning("Row %d does not have enough
>>> elements. Skipping.", index)
>>>                     continue
>>>
>>>                 meta = data.new_metadata(file.name, index)  # Beancount
>>> meta
>>>                 date = datetime.datetime.strptime(row[0], "%m/%d/%Y").
>>> date()  # Parse the date of the transaction
>>>
>>>                 # Extracting relevant information from the description
>>> to determine payee and other_account
>>>                 description = row[1]  # Assuming description is in the
>>> second column
>>>                 payee = ""  # Placeholder, modify this based on the
>>> description
>>>                 other_account = "Expenses"  # Placeholder, modify this
>>> based on the description
>>>
>>>                 # Check if the description contains "CARD PMT"
>>>                 if "CARD PMT" in description:
>>>                     payee = "PNC Cash Rewards"
>>>                     other_account = "Liabilities:PNC:CashRewards"
>>>
>>>                 # Check if this is an ATM withdrawal
>>>                 # and then subtract their ATM Fee and put that in
>>> separate expense
>>>
>>>                 if "ATM" in description:
>>>                     other_account = "Assets:Cash"
>>>
>>>
>>>                 # Determining the credit/debit type based on
>>> withdrawals and deposits
>>>                 withdrawal = row[2]  # Withdrawals amount
>>>                 deposit = row[3]  # Deposits amount
>>>
>>>                 if withdrawal:
>>>                     units = -amount.Amount(D(withdrawal.replace('$', '')),
>>> self.currency)  # Using withdrawal amount
>>>                 elif deposit:
>>>                     units = amount.Amount(D(deposit.replace('$', '')),
>>> self.currency)  # Using deposit amount
>>>                 else:
>>>                     logging.warning("Invalid row: %s", row)
>>>                     continue
>>>
>>>                 account = self.account  # Modify this according to your
>>> data
>>>
>>>                 txn = data.Transaction(
>>>                     meta,
>>>                     date,
>>>                     None,  # No specific flag
>>>                     payee,
>>>                     description,
>>>                     data.EMPTY_SET,
>>>                     data.EMPTY_SET,
>>>                     [
>>>                         data.Posting(
>>>                             account, units, None, None, None, None
>>>                         ),
>>>                         data.Posting(
>>>                             other_account, -units, None, None, None,
>>> None
>>>                         ),
>>>                     ],
>>>                 )
>>>
>>>                 entries.append(txn)
>>>
>>>         return entries
>>>
>>> This works well and I get this kind of output...
>>>
>>> 2019-03-01 None "ATM WITHDRAWAL"
>>>   Assets:PNC:Checking  -407.99 USD
>>>   Assets:Cash          407.99 USD
>>>
>>> In the section where the ATM transactions are figured out through the
>>> descriptor I added this...
>>>
>>> # Check if this is an ATM withdrawal
>>> # and then subtract their ATM Fee and put that in separate expense
>>>
>>>                 if "ATM" in description:
>>>                     other_account = "Assets:Cash"
>>>
>>> # Calculate the ATM fee
>>>                     atm_fee_amount = D("0.00")  # Initialize ATM fee
>>> amount
>>>                     withdrawal_amount = abs(units.number)  # Absolute
>>> value of the withdrawal amount
>>>
>>>                     # Check if the withdrawal amount is greater than an
>>> even number
>>>                     if withdrawal_amount % 2 != 0:  # If it's not an
>>> even number
>>>                         atm_fee_amount = D(withdrawal_amount - (
>>> withdrawal_amount // 2) * 2)  # Calculate the fee as the remainder
>>> after division by 2
>>>
>>>                     # Adjust the ATM fee amount
>>>                     atm_fee_amount = -atm_fee_amount
>>>
>>>                     # Convert the ATM fee amount to a beancount.Amount
>>> object
>>>                     atm_fee = amount.Amount(atm_fee_amount, self
>>> .currency)
>>>                     # Create a posting for the ATM fee
>>>                     atm_fee_posting = data.Posting(
>>>                         "Expenses:BankFees:ATM", atm_fee_amount, None,
>>> None, None, None
>>>                     )
>>>                     # Adjust the units for the main account posting
>>>                     main_account_units = units + atm_fee_amount
>>>                     # Add the adjusted main account posting
>>>                     main_account_posting = data.Posting(
>>>                         account, main_account_units, None, None, None,
>>> None
>>>                     )
>>>                     txn.postings.append(main_account_posting)
>>>                     # Add the ATM fee posting to the transaction
>>>                     txn.postings.append(atm_fee_posting)
>>>
>>>  But I can't seem to get it to append properly to the postings.
>>>
>>> I'd like the output to look like this...
>>>
>>> 2019-03-01 None "ATM WITHDRAWAL"
>>>   Assets:PNC:Checking             -407.99 USD
>>>   Assets:Cash                               400.00 USD
>>>   Expenses:BankFees:ATM        -7.99 USD
>>>
>>> Any help would be appreciated.
>>>
>>> I'll probably figure it out eventually, but if anyone has done this
>>> already I would love to hear how you did it.  So far I have been sort of
>>> Frankensteining pieces from Beancount examples I've found so I my
>>> understanding of everything is not great yet.
>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Beancount" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/beancount/6225321a-b905-4b23-ac5d-6eeb44289122n%40googlegroups.com
>>> <https://groups.google.com/d/msgid/beancount/6225321a-b905-4b23-ac5d-6eeb44289122n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "Beancount" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/beancount/af0f6e5b-f236-4b40-b1dc-60b91d2e31a1n%40googlegroups.com
> <https://groups.google.com/d/msgid/beancount/af0f6e5b-f236-4b40-b1dc-60b91d2e31a1n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/beancount/CAFXPr0veRa%3DsQTEQm9cx6K9oRw33733Bo%2B-c2CdxhB37DGyELQ%40mail.gmail.com.

Reply via email to