def list_payments(event_id=None): """Api endpoint for listing all payments associated to an event. :param event_id: The primary key of the event we're listing the payments of :type event_id: int """ if event_id is not None: event = Event.query.get(event_id) if event is None: return abort(404) if not event.has_edit_rights(current_user) and not current_user.is_accountant(): return abort(403) else: if not current_user.is_accountant(): return abort(403) page = int(request.args.get("page")) size = int(request.args.get("size")) filters = {k: v for (k, v) in request.args.items() if k.startswith("filters")} result = extract_payments(event_id, page, size, filters) data = EventPaymentSchema(many=True).dump(result.items) response = {"data": data, "last_page": result.pages} return json.dumps(response), 200, {"content-type": "application/json"}
def list_payments(event_id): """Route for listing all payments associated to an event :param event_id: The primary key of the event we're listing the prices of :type event_id: int """ event = Event.query.get(event_id) if event is None: flash("Événement inexistant", "error") return redirect(url_for("event.index")) if not current_user.is_accountant() and not event.has_edit_rights( current_user): flash("Accès refusé", "error") return redirect(url_for("event.view_event", event_id=event_id)) return render_template("payment/payment_list.html", event=event)
def payment_details(payment_id): """Route for displaying details about a given payment :param payment_id: Payment primary key :type payment_id: int """ payment = Payment.query.get(payment_id) if payment is None: flash("Accès refusé", "error") return redirect(url_for("event.index")) event = payment.item.event if not current_user.is_accountant(): if event is None or not event.has_edit_rights(current_user): flash("Accès refusé", "error") return redirect(url_for("event.view_event", event_id=event.id)) return render_template( "payment/payment_details.html", payment=payment, event=event, )
def report_offline(registration_id, payment_id=None): """Route for entering/editing an offline payment :param registration_id: The registration associated to the payment :type registration_id: int :param payment_id: If editing an existing payment, its primary key. Defaults to None :type payment_id: int, optional """ registration = Registration.query.get(registration_id) if registration is None: flash("Inscription invalide", "error") return redirect(url_for("event.index")) event = registration.event if not current_user.is_accountant(): if event is None or not event.has_edit_rights(current_user): flash("Accès refusé", "error") return redirect(url_for("event.view_event", event_id=event.id)) payment = None if payment_id is not None: payment = Payment.query.get(payment_id) if (payment is None or payment.registration_id != int(registration_id) or not payment.is_offline()): flash("Paiement invalide", "error") return redirect(url_for("event.view_event", event_id=event.id)) form = OfflinePaymentForm(registration, obj=payment) all_valid = False if form.validate_on_submit(): item_price = ItemPrice.query.get(form.item_price.data) if (item_price is None or item_price.item.event_id != event.id or not item_price.is_available_to_user(registration.user)): flash("Tarif invalide.", "error") else: all_valid = True if all_valid: if payment is None: payment = Payment(registration=registration, item_price=item_price) else: payment.item_price_id = item_price.id payment.payment_item_id = item_price.item.id payment.amount_charged = item_price.amount form.populate_obj(payment) payment.reporter_id = current_user.id if payment.status == PaymentStatus.Refunded: payment.refund_time = current_time() else: payment.finalization_time = current_time() db.session.add(payment) if hasattr( form, "make_active") and form.make_active and form.make_active.data: registration.status = RegistrationStatus.Active db.session.add(registration) db.session.commit() return redirect(url_for(".list_payments", event_id=event.id)) return render_template( "basicform.html", form=form, title="Paiement hors-ligne", subtitle= f"Inscription de {registration.user.full_name()} à {event.title}", )
def export_payments(event_id=None): """Create an Excel document listing all approved payments associated to an event :param event_id: The primary key of the event we're listing the prices of :type event_id: int :return: The Excel file with the payments. """ # Check that the user is allowed to retrieve the payments if event_id is not None: event = Event.query.get(event_id) if event is None: return abort(404) if not current_user.is_accountant() and not event.has_edit_rights( current_user): return abort(403) else: if not current_user.is_accountant(): return abort(403) # Fetch all associated payments filters = { k: v for (k, v) in request.args.items() if k.startswith("filters") } payments = extract_payments(event_id, None, None, filters) # Create the excel document wb = Workbook() ws = wb.active FIELDS = { "item.event.activity_type_names": "Activités", "item.event.main_leader.first_name": "Prénom encadrant", "item.event.main_leader.last_name": "Nom encadrant", "item.event.title": "Collective", "item.event.start": "Date de la collective", "buyer.license": "Licence", "buyer.first_name": "Prénom", "buyer.last_name": "Nom", "buyer.mail": "Email", "buyer.phone": "Téléphone", "item.title": "Objet", "price.title": "Tarif", "amount_paid": "Prix payé", "finalization_time": "Date du paiement", "payment_status_str": "État", "refund_time": "Date de remboursement", "payment_type_str": "Type", "processor_order_ref": "Référence", } ws.append(list(FIELDS.values())) for payment in payments: payment.payment_type_str = payment.payment_type.display_name() payment.payment_status_str = payment.status.display_name() ws.append([str(deepgetattr(payment, field, "-")) for field in FIELDS]) # set column width for c in "BCDEFGIK": ws.column_dimensions[c].width = 25 for c in "AHJLM": ws.column_dimensions[c].width = 16 out = BytesIO() wb.save(out) out.seek(0) time_str = current_time().strftime("%d_%m_%Y %H_%M") if event_id is not None: title = slugify(event.title) filename = f"CAF Annecy - Export paiements {title} au {time_str}.xlsx" else: filename = f"CAF Annecy - Export paiements au {time_str}.xlsx" return send_file( out, mimetype= "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", attachment_filename=filename, as_attachment=True, )