zap-me / zap_payments

MIT License
0 stars 1 forks source link

email notifications #12

Closed djpnewton closed 4 years ago

djpnewton commented 4 years ago

We should allow the user to enter an email address to get notifications about their payment

  1. Add 'email' to the Invoice table (we might need to add a 'status' column too)
  2. Show the email field in the HTML forms (above or below the amount field)
    • validate the email field if not null and show an error if not a valid email
  3. Include the email when creating the invoice
  4. Add a timer that runs every 10 minutes
    • the timer will get all invoices with a non-null email and a (status != STATUS_EXPIRED && status != STATUS_SENT)
    • get the broker order status from bronze for each invoice
    • send an email if the status is different (and save the new status)
eoliveros commented 4 years ago

We should allow the user to enter an email address to get notifications about their payment

  1. Add 'email' to the Invoice table (we might need to add a 'status' column too)

added email_address field aswell as a status field.

  1. Show the email field in the HTML forms (above or below the amount field)

    • validate the email field if not null and show an error if not a valid email

if no email address is entered, it will error "enter an email address" and use re.match for the email pattern.

found out how to make the form remember what was placed in the form when it fails.

will look at 3 and 4

  1. Include the email when creating the invoice

  2. Add a timer that runs every 10 minutes

    • the timer will get all invoices with a non-null email and a (status != STATUS_EXPIRED && status != STATUS_SENT)
    • get the broker order status from bronze for each invoice
    • send an email if the status is different (and save the new status)
djpnewton commented 4 years ago

for a timer we need to use a gevent thread like this: https://github.com/zap-me/zap_bill_payment/blob/master/timer.py

eoliveros commented 4 years ago

Include the email when creating the invoice

Added email_address in creating invoice

force push to the repo.

eoliveros commented 4 years ago

for a timer we need to use a gevent thread like this: https://github.com/zap-me/zap_bill_payment/blob/master/timer.py

I'm not sure what gevent thread does and i can't use another way of doing the timer?

djpnewton commented 4 years ago

force push to the repo.

what repo?

I'm not sure what gevent thread does and i can't use another way of doing the timer?

no, but you can see how I created a timer

eoliveros commented 4 years ago

force push to the repo.

what repo?

just created a PR to show what ive done for steps 1 -3

I'm not sure what gevent thread does and i can't use another way of doing the timer?

no, but you can see how I created a timer

trying to create the timer, not yet PR still trying to understand

eoliveros commented 4 years ago

testing the following for the timer... very simple timer script:

def test_timer():
    seconds = 60
    now = time.time()
    elapsed = now
    while 1:
        now = time.time()
        print("now - elapsed: {}".format(now - elapsed))
        return("now - elapsed: {}".format(now - elapsed))
        while now - elapsed >= seconds:
            elapsed += seconds
        time.sleep(5)
    return None

So every 5 seconds it will sleep and print a message.

at the end of the app.py, I am running i added test_timer( ) to run when the app.py is running.

        if timer:
            timer.kill()
    test_timer_status()

No errors. But can't see if its running or not. trying to see if i could make the message appear to make sure tis running.

eoliveros commented 4 years ago

just deployed the latest update for this branch. It looks we made the email (notification) to be optional, before the email was mandatory so it cant be empty. Now it only checks if it matches the format.

eoliveros commented 4 years ago

is this going to work?

def email_invoices_timer_callback():
    print("email_invoices_timer_callback()..")
    invoices = Invoice.all_with_email_and_not_terminated(db.session)
    for invoice in invoices:
        print(invoice)
        #TODO
        broker_status = broker_status # Need to define this
        data = json.loads(invoice)
        email = data['email']
        amount_cents_nzd = data['amount_cents_nzd']
        amount_cents_zap = data['amount_cents_zap']
        broker_token = data['broker_token']
        status = data['status']
        # IF BROKER STATUS != status
        if status != broker_status:
            status = broker_status
            update_invoice = Invoice.query().filter(and_(Invoice.email = email, Invoice.amount_cents_nzd = amount_cents_nzd, Invoice.amount_cents_zap = amount_cents_nzd, Invoice.broker_token = broker_token)
            update_invoice.status = status
            db.session.commit()

thinking of doing something like above, think that's gonna work? The update i did is from "TODO" and afterwards.

djpnewton commented 4 years ago

data = json.loads(invoice) is not required, invoice is an object from the database

bronze_order_status() is the function to get an 'order' object (as a dictionary) and therefore its status

eoliveros commented 4 years ago

data = json.loads(invoice) is not required, invoice is an object from the database

bronze_order_status() is the function to get an 'order' object (as a dictionary) and therefore its status

how about this one:

def email_invoices_timer_callback():
    print("email_invoices_timer_callback()..")
    invoices = Invoice.all_with_email_and_not_terminated(db.session)
    for invoice in invoices:
        print(invoice)
        #TODO
        email = invoice.email
        amount_cents_nzd = invoice.amount_cents_nzd
        amount_cents_zap = invoice.amount_cents_zap
        broker_token = invoice.broker_token
        status = invoice.status
        order = bronze_order_status(invoice)
        if invoice.status != order.status:
            invoice.status = order.status
            update_invoice = Invoice.query().filter(and_(Invoice.email = email, Invoice.amount_cents_nzd = amount_cents_nzd, Invoice.amount_cents_zap = amount_cents_zap, Invoice.broker_token = broker_token)
            update_invoice.status = status
            db.session.commit()
djpnewton commented 4 years ago

something like that but you need to also email

eoliveros commented 4 years ago

something like that but you need to also email

yeah trying to look at how the email part is working. As far as i could from looking at another app:

mail = MailSendGrid(app)

And from the doc that I've seen, somewhere should be calling:

mail.send_mail(
    from_email='someone@yourdomain.com',
    to_email=[Email('test1@example.com'), Email('test2@example.com')],
    subject='Subject'
    text='Body',
)

but cant locate anything like above on zapm_server.

djpnewton commented 4 years ago

the timers and email were a bit more difficult then I thought, take a look at what I added to the branch

eoliveros commented 4 years ago

getting error when submitting a bill payment: image

so cant really test

djpnewton commented 4 years ago

you need to set bronze api key correctly