Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various #2437

Merged
merged 2 commits into from
Sep 2, 2024
Merged

Various #2437

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 19 additions & 16 deletions liberapay/models/participant.py
Original file line number Diff line number Diff line change
Expand Up @@ -2730,36 +2730,41 @@ def find_partial_match(new_sp, current_schedule_map):
(self.id,))

# Get renewable tips
next_payday = compute_next_payday_date()
renewable_tips = cursor.all("""
SELECT t.*::tips, tippee_p
SELECT t.*::tips, tippee_p, last_pt::payin_transfers
FROM current_tips t
JOIN participants tippee_p ON tippee_p.id = t.tippee
LEFT JOIN LATERAL (
SELECT pt.*
FROM payin_transfers pt
WHERE pt.payer = t.tipper
AND coalesce(pt.team, pt.recipient) = t.tippee
ORDER BY pt.ctime DESC
LIMIT 1
) last_pt ON true
WHERE t.tipper = %s
AND t.renewal_mode > 0
AND t.paid_in_advance IS NOT NULL
AND tippee_p.status = 'active'
AND ( tippee_p.goal IS NULL OR tippee_p.goal >= 0 )
AND tippee_p.is_suspended IS NOT TRUE
AND tippee_p.payment_providers > 0
AND NOT EXISTS (
SELECT 1
FROM ( SELECT pt.*
FROM payin_transfers pt
WHERE pt.payer = t.tipper
AND coalesce(pt.team, pt.recipient) = t.tippee
ORDER BY pt.ctime DESC
LIMIT 1
) pt
WHERE pt.status IN ('pending', 'failed')
)
ORDER BY t.tippee
""", (self.id,))
for tip, tippee_p in renewable_tips:
for tip, tippee_p, last_pt in renewable_tips:
tip.tippee_p = tippee_p
tip.periodic_amount = tip.periodic_amount.convert_if_currency_is_phased_out()
tip.amount = tip.amount.convert_if_currency_is_phased_out()
tip.paid_in_advance = tip.paid_in_advance.convert_if_currency_is_phased_out()
renewable_tips = [tip for tip, tippee_p in renewable_tips]
tip.due_date = tip.compute_renewal_due_date(next_payday, cursor)
renewable_tips = [
tip for tip, tippee_p, last_pt in renewable_tips
if last_pt.id is None or
last_pt.status == 'succeeded' or
last_pt.status == 'failed' and
last_pt.ctime.date() < (tip.due_date - timedelta(weeks=1))
]

# Get the existing schedule
current_schedule = cursor.all("""
Expand Down Expand Up @@ -2864,10 +2869,8 @@ def find_partial_match(new_sp, current_schedule_map):

# Group the tips into payments
# 1) Group the tips by renewal_mode and currency.
next_payday = compute_next_payday_date()
naive_tip_groups = defaultdict(list)
for tip in renewable_tips:
tip.due_date = tip.compute_renewal_due_date(next_payday, cursor)
naive_tip_groups[(tip.renewal_mode, tip.amount.currency)].append(tip)
del renewable_tips
# 2) Subgroup by payment processor and geography.
Expand Down
5 changes: 5 additions & 0 deletions liberapay/models/payin_transfer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from postgres.orm import Model


class PayinTransfer(Model):
typname = "payin_transfers"
5 changes: 3 additions & 2 deletions liberapay/wireup.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
from liberapay.models.exchange_route import ExchangeRoute
from liberapay.models.participant import Participant
from liberapay.models.payin import Payin
from liberapay.models.payin_transfer import PayinTransfer
from liberapay.models.repository import Repository
from liberapay.models.tip import Tip
from liberapay.security.crypto import Cryptograph
Expand Down Expand Up @@ -117,8 +118,8 @@ def back_as_Object(cols, vals):
db.back_as_registry[Object] = db.back_as_registry['Object'] = back_as_Object

models = (
_AccountElsewhere, AccountElsewhere, _Community, Community,
Encrypted, ExchangeRoute, Participant, Payin, Repository, Tip,
_AccountElsewhere, AccountElsewhere, _Community, Community, Encrypted,
ExchangeRoute, Participant, Payin, PayinTransfer, Repository, Tip,
)
for model in models:
db.register_model(model)
Expand Down
2 changes: 1 addition & 1 deletion www/%username/edit/avatar.spt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ if request.method == 'POST':

if src not in constants.AVATAR_SOURCES:
raise response.invalid_input(src, 'src', 'body')
if '@' not in email:
if email and '@' not in email:
raise BadEmailAddress(email)

new_avatar_url = participant.update_avatar(src+':', avatar_email=email)
Expand Down
Loading