Lock customer page after choice, archive files on revision, add file checkboxes for delivery
This commit is contained in:
parent
51d1b4a4d9
commit
0f6b68cf5d
4 changed files with 144 additions and 48 deletions
83
app.py
83
app.py
|
|
@ -234,11 +234,29 @@ def revise(token):
|
|||
Customer asked for changes. Store the note and reset status to 'songs_uploaded'
|
||||
so the operator sees it in the dashboard queue.
|
||||
"""
|
||||
req = get_request_by_token(token)
|
||||
if not req:
|
||||
abort(404)
|
||||
note = request.form.get('revision_note', '').strip()
|
||||
update_request(req['id'], revision_note=note, status='revisions_requested')
|
||||
# Increment revision counter and archive current files before new versions are uploaded.
|
||||
req = get_request_by_token(token)
|
||||
if req:
|
||||
new_count = (req.get('revision_count') or 0) + 1
|
||||
upload_dir = Path(current_app.config['UPLOAD_FOLDER']) / str(req['id'])
|
||||
if upload_dir.exists():
|
||||
for field, version in (('song_a_path', 'A'), ('song_b_path', 'B')):
|
||||
path = req.get(field)
|
||||
if path and Path(path).exists():
|
||||
old = Path(path)
|
||||
archived = upload_dir / f"Rev{new_count}-{old.name}"
|
||||
try:
|
||||
old.rename(archived)
|
||||
# Keep path pointing to the archived file; operator will upload new files.
|
||||
req[field] = str(archived)
|
||||
except OSError:
|
||||
pass
|
||||
update_request(req['id'], revision_note=note, status='revisions_requested',
|
||||
song_a_path=req.get('song_a_path'), song_b_path=req.get('song_b_path'),
|
||||
customer_approved='none', revision_count=new_count)
|
||||
else:
|
||||
abort(404)
|
||||
|
||||
# NOTE: No operator email is sent; the dashboard is the single queue.
|
||||
flash('Your feedback has been saved. We will regenerate and update you.', 'success')
|
||||
|
|
@ -323,6 +341,16 @@ def admin_request(rid):
|
|||
def basename(path):
|
||||
return Path(path).name if path else ''
|
||||
|
||||
# Collect any extra MP3 files in the request folder (archived revisions).
|
||||
upload_dir = Path(current_app.config['UPLOAD_FOLDER']) / str(rid)
|
||||
current_paths = {req['song_a_path'], req['song_b_path']}
|
||||
extra_files = []
|
||||
if upload_dir.exists():
|
||||
for f in upload_dir.iterdir():
|
||||
if f.is_file() and f.suffix.lower() == '.mp3' and str(f) not in current_paths:
|
||||
extra_files.append(str(f))
|
||||
extra_files.sort()
|
||||
|
||||
if request.method == 'POST':
|
||||
action = request.form.get('action')
|
||||
|
||||
|
|
@ -366,34 +394,35 @@ def admin_request(rid):
|
|||
|
||||
elif action == 'mark_paid_deliver':
|
||||
# Finalize: record Square payment ref, attach approved MP3s, email customer.
|
||||
if req['customer_approved'] == 'none':
|
||||
flash('Customer has not approved a version yet.', 'error')
|
||||
else:
|
||||
payment_ref = request.form.get('square_payment_ref', '').strip()
|
||||
if not payment_ref:
|
||||
flash('Square payment reference is required.', 'error')
|
||||
return redirect(url_for('admin_request', rid=rid))
|
||||
payment_ref = request.form.get('square_payment_ref', '').strip()
|
||||
if not payment_ref:
|
||||
flash('Square payment reference is required.', 'error')
|
||||
return redirect(url_for('admin_request', rid=rid))
|
||||
|
||||
attachments = []
|
||||
if req['customer_approved'] in ('a', 'both') and req['song_a_path']:
|
||||
a_name = Path(req['song_a_path']).name
|
||||
attachments.append((req['song_a_path'], a_name))
|
||||
if req['customer_approved'] in ('b', 'both') and req['song_b_path']:
|
||||
b_name = Path(req['song_b_path']).name
|
||||
attachments.append((req['song_b_path'], b_name))
|
||||
# Build list of selected files from checkboxes.
|
||||
selected = request.form.getlist('deliver_file')
|
||||
if not selected:
|
||||
flash('Select at least one file to deliver.', 'error')
|
||||
return redirect(url_for('admin_request', rid=rid))
|
||||
|
||||
player_link = f"{current_app.config['PUBLIC_BASE_URL']}/play/{req['player_token']}"
|
||||
body = f"Hi {req['name']},\n\nThanks for your payment! Your approved song is attached to this email.\n\nIf you selected both versions, you'll find two MP3 files.\n\nYou can also keep streaming them here: {player_link}\n\nEnjoy!\n\n— {current_app.config['BOOTH_NAME']}"
|
||||
try:
|
||||
send_email(req['email'], 'Your theme song files are here!', body, attachments=attachments)
|
||||
update_request(rid, square_payment_ref=payment_ref, delivery_sent_at=now_utc(), status='delivered')
|
||||
flash('Delivery email sent with MP3 attachments.', 'success')
|
||||
except Exception as e:
|
||||
flash(f'Failed to send delivery email: {e}', 'error')
|
||||
attachments = []
|
||||
for path in selected:
|
||||
p = Path(path)
|
||||
if p.exists():
|
||||
attachments.append((str(p), p.name))
|
||||
|
||||
player_link = f"{current_app.config['PUBLIC_BASE_URL']}/play/{req['player_token']}"
|
||||
body = f"Hi {req['name']},\n\nThanks for your payment! Your selected song(s) are attached to this email.\n\nYou can also keep streaming them here: {player_link}\n\nEnjoy!\n\n— {current_app.config['BOOTH_NAME']}"
|
||||
try:
|
||||
send_email(req['email'], 'Your theme song files are here!', body, attachments=attachments)
|
||||
update_request(rid, square_payment_ref=payment_ref, delivery_sent_at=now_utc(), status='delivered')
|
||||
flash('Delivery email sent with MP3 attachments.', 'success')
|
||||
except Exception as e:
|
||||
flash(f'Failed to send delivery email: {e}', 'error')
|
||||
|
||||
return redirect(url_for('admin_request', rid=rid))
|
||||
|
||||
return render_template('admin/request.html', req=req, statuses=STATUS_LABELS, file_exists=file_exists, basename=basename)
|
||||
return render_template('admin/request.html', req=req, statuses=STATUS_LABELS, file_exists=file_exists, basename=basename, extra_files=extra_files)
|
||||
|
||||
|
||||
@app.route('/admin/request/<int:rid>/delete', methods=['POST'])
|
||||
|
|
|
|||
Reference in a new issue