Created
September 15, 2016 09:00
-
-
Save panki/ce67e68e72f01154d1f5a8cd08f2720d to your computer and use it in GitHub Desktop.
audit logs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import json | |
import logging | |
from .models import * | |
from . import tables | |
from payme import utm | |
from payme.forms import form_to_dict | |
logger = logging.getLogger(__name__) | |
# account | |
@db.atomic | |
def account_created(req, account_id, recipient=True, tx=None): | |
typ = ACCOUNT_RECIPIENT_CREATED if recipient else ACCOUNT_PAYER_CREATED | |
return _create(req, tx, typ, account_id=account_id) | |
# admin | |
@db.atomic | |
def admin_created(req, admin_id, tx=None): | |
return _create(req, tx, ADMIN_USERS_ADMIN_CREATED, admin_user_id=admin_id) | |
@db.atomic | |
def admin_user_recreated(req, user_id, tx=None): | |
return _create(req, tx, ADMIN_USERS_RECREATED, admin_user_id=user_id) | |
@db.atomic | |
def admin_user_deleted(req, user_id, tx=None): | |
return _create(req, tx, ADMIN_USERS_DELETED, admin_user_id=user_id) | |
@db.atomic | |
def admin_user_added_to_admins(req, user_id, tx=None): | |
return _create(req, tx, ADMIN_USERS_ADDED_TO_ADMINS, admin_user_id=user_id) | |
@db.atomic | |
def admin_user_deleted_from_admins(req, user_id, tx=None): | |
return _create(req, tx, ADMIN_USERS_DELETED_FROM_ADMINS, admin_user_id=user_id) | |
@db.atomic | |
def admin_user_email_confirmed(req, user_id, tx=None): | |
return _create(req, tx, ADMIN_USERS_EMAIL_CONFIRMED, admin_user_id=user_id) | |
@db.atomic | |
def admin_user_password_changed(req, user_id, tx=None): | |
return _create(req, tx, ADMIN_USERS_PASSWORD_CHANGED, admin_user_id=user_id) | |
# admin roles | |
@db.atomic | |
def admin_role_created(req, admin_role_id, tx=None): | |
return _create(req, tx, ADMIN_ROLES_CREATED, admin_role_id=admin_role_id) | |
@db.atomic | |
def admin_role_updated(req, admin_role_id, tx=None): | |
return _create(req, tx, ADMIN_ROLES_UPDATED, admin_role_id=admin_role_id) | |
@db.atomic | |
def admin_role_deleted(req, admin_role_id, tx=None): | |
return _create(req, tx, ADMIN_ROLES_DELETED, admin_role_id=admin_role_id) | |
@db.atomic | |
def admin_role_member_added(req, admin_role_id, admin_user_id, tx=None): | |
return _create( | |
req, tx, ADMIN_ROLES_MEMBER_ADDED, | |
admin_role_id=admin_role_id, | |
admin_user_id=admin_user_id) | |
@db.atomic | |
def admin_role_member_deleted(req, admin_role_id, admin_user_id, tx=None): | |
return _create( | |
req, tx, ADMIN_ROLES_MEMBER_DELETED, | |
admin_role_id=admin_role_id, | |
admin_user_id=admin_user_id) | |
# alfabank_tx | |
@db.atomic | |
def alfabank_tx_created(req, transaction, tx=None): | |
return _create( | |
req, tx, ALFABANK_TX_CREATED, | |
alfabank_tx_id=transaction.id, | |
invoice_id=transaction.invoice_id, | |
card_id=transaction.card_id) | |
@db.atomic | |
def alfabank_tx_start_response(req, transaction, response, tx=None): | |
return _create( | |
req, tx, ALFABANK_TX_START_RESPONSE, | |
alfabank_tx_id=transaction.id, | |
invoice_id=transaction.invoice_id, | |
card_id=transaction.card_id, | |
payload=response) | |
@db.atomic | |
def alfabank_tx_started(req, transaction, response, tx=None): | |
return _create( | |
req, tx, ALFABANK_TX_STARTED, | |
alfabank_tx_id=transaction.id, | |
invoice_id=transaction.invoice_id, | |
card_id=transaction.card_id, | |
payload=response.to_json(safe=True)) | |
@db.atomic | |
def alfabank_tx_failed_to_start(req, transaction, e, tx=None): | |
return _create( | |
req, tx, ALFABANK_TX_FAILED_TO_START, | |
alfabank_tx_id=transaction.id, | |
invoice_id=transaction.invoice_id, | |
card_id=transaction.card_id, | |
payload=str(e)) | |
@db.atomic | |
def alfabank_tx_confirmed(req, transaction, confirm_form, tx=None): | |
return _create( | |
req, tx, ALFABANK_TX_CONFIRMED, | |
alfabank_tx_id=transaction.id, | |
invoice_id=transaction.invoice_id, | |
card_id=transaction.card_id) | |
@db.atomic | |
def alfabank_tx_cofirm_request(req, transaction, confirm_form, tx=None): | |
payload = json.dumps(form_to_dict(confirm_form), ensure_ascii=False) | |
return _create( | |
req, tx, ALFABANK_TX_CONFIRM_REQUEST, | |
alfabank_tx_id=transaction.id, | |
invoice_id=transaction.invoice_id, | |
card_id=transaction.card_id, | |
payload=payload) | |
@db.atomic | |
def alfabank_tx_cofirm_failure(req, transaction, e, tx=None): | |
payload = str(e) | |
return _create( | |
req, tx, ALFABANK_TX_CONFIRM_FAILURE, | |
alfabank_tx_id=transaction.id, | |
invoice_id=transaction.invoice_id, | |
card_id=transaction.card_id, | |
payload=payload) | |
@db.atomic | |
def alfabank_tx_complete_request(req, transaction, client_form, tx=None): | |
return _create( | |
req, tx, ALFABANK_TX_COMPLETE_REQUEST, | |
alfabank_tx_id=transaction.id, | |
invoice_id=transaction.invoice_id, | |
card_id=transaction.card_id, | |
payload=client_form.to_json(safe=True)) | |
@db.atomic | |
def alfabank_tx_complete_response(req, transaction, response, tx=None): | |
return _create( | |
req, tx, ALFABANK_TX_COMPLETE_RESPONSE, | |
alfabank_tx_id=transaction.id, | |
invoice_id=transaction.invoice_id, | |
card_id=transaction.card_id, | |
payload=response) | |
@db.atomic | |
def alfabank_tx_completed(req, transaction, tx=None): | |
return _create( | |
req, tx, ALFABANK_TX_COMPLETED, | |
alfabank_tx_id=transaction.id, | |
card_id=transaction.card_id, | |
invoice_id=transaction.invoice_id) | |
@db.atomic | |
def alfabank_tx_complete_failure(req, transaction, e, tx=None): | |
return _create( | |
req, tx, ALFABANK_TX_COMPLETE_FAILURE, | |
alfabank_tx_id=transaction.id, | |
invoice_id=transaction.invoice_id, | |
card_id=transaction.card_id, | |
payload=str(e)) | |
# alfabank_fee | |
@db.atomic | |
def alfabank_fee_calc_started(req, invoice_id, client_form, tx=None): | |
return _create( | |
req, tx, ALFABANK_FEE_CALC_STARTED, | |
invoice_id=invoice_id, | |
payload=client_form.to_json(safe=True)) | |
@db.atomic | |
def alfabank_fee_calc_failed(req, invoice_id, e, tx=None): | |
return _create( | |
req, tx, ALFABANK_FEE_CALC_FAILED, | |
invoice_id=invoice_id, | |
payload=str(e)) | |
@db.atomic | |
def alfabank_fee_calc_response(req, invoice_id, resp, tx=None): | |
return _create( | |
req, tx, ALFABANK_FEE_CALC_RESPONSE, | |
invoice_id=invoice_id, | |
payload=resp.to_json(safe=True)) | |
# auth | |
@db.atomic | |
def auth_token_created(req, token, tx=None): | |
return _create( | |
req, tx, AUTH_TOKEN_CREATED, | |
auth_token_id=token.id, | |
account_id=token.account_id, | |
invoice_id=token.invoice_id) | |
@db.atomic | |
def auth_session_created(req, session, tx=None): | |
return _create( | |
req, tx, AUTH_SESSION_CREATED, | |
account_id=session.account_id, | |
auth_token_id=session.token_id, | |
auth_session_id=session.id) | |
# cards | |
@db.atomic | |
def card_created(req, card, tx=None): | |
return _create( | |
req, tx, CARDS_CREATED, | |
account_id=card.account_id, | |
card_id=card.id, | |
payload=card.masked_number) | |
# devices | |
@db.atomic | |
def device_created(req, device, tx=None): | |
return _create( | |
req, tx, DEVICES_CREATED, | |
device_id=device.id) | |
# emails | |
@db.atomic | |
def email_created(req, email, tx=None): | |
return _create( | |
req, tx, EMAILS_CREATED, | |
email_id=email.id, | |
account_id=email.account_id, | |
invoice_id=email.invoice_id, | |
auth_token_id=email.auth_token_id) | |
@db.atomic | |
def email_cancelled(req, email, tx=None): | |
return _create( | |
req, tx, EMAILS_CANCELLED, | |
email_id=email.id, | |
account_id=email.account_id, | |
invoice_id=email.invoice_id) | |
@db.atomic | |
def email_failed(req, email, message, tx=None): | |
return _create( | |
req, tx, EMAILS_FAILED, | |
email_id=email.id, | |
account_id=email.account_id, | |
invoice_id=email.invoice_id, | |
payload=message) | |
@db.atomic | |
def email_sent(req, email, tx=None): | |
return _create( | |
req, tx, EMAILS_SENT, | |
email_id=email.id, | |
account_id=email.account_id, | |
invoice_id=email.invoice_id) | |
@db.atomic | |
def email_delivered(req, email, tx=None): | |
return _create( | |
req, tx, EMAILS_DELIVERED, | |
email_id=email.id, | |
account_id=email.account_id, | |
invoice_id=email.invoice_id) | |
@db.atomic | |
def email_opened(req, email, tx=None): | |
return _create( | |
req, tx, EMAILS_OPENED, | |
email_id=email.id, | |
account_id=email.account_id, | |
invoice_id=email.invoice_id) | |
# invoices | |
@db.atomic | |
def invoice_created(req, invoice, tx=None): | |
return _create( | |
req, tx, INVOICES_CREATED, | |
account_id=invoice.owner_id, # In case req.account_id != invoice.owner_id | |
invoice_id=invoice.id) | |
@db.atomic | |
def invoice_sent(req, invoice, tx=None): | |
return _create(req, tx, INVOICES_SENT, invoice_id=invoice.id) | |
@db.atomic | |
def invoice_cancelled(req, invoice, tx=None): | |
return _create(req, tx, INVOICES_CANCELLED, invoice_id=invoice.id) | |
@db.atomic | |
def invoice_refused(req, invoice, tx=None): | |
return _create(req, tx, INVOICES_REFUSED, invoice_id=invoice.id) | |
@db.atomic | |
def invoice_expired(req, invoice, tx=None): | |
return _create(req, tx, INVOICES_EXPIRED, invoice_id=invoice.id) | |
@db.atomic | |
def invoice_reminded(req, invoice, tx=None): | |
return _create(req, tx, INVOICES_REMINDED, invoice_id=invoice.id) | |
@db.atomic | |
def invoice_failed(req, invoice, message, tx=None): | |
return _create(req, tx, INVOICES_FAILED, invoice_id=invoice.id, payload=message) | |
@db.atomic | |
def invoice_paid(req, invoice, tx=None): | |
return _create(req, tx, INVOICES_PAID, invoice_id=invoice.id) | |
@db.atomic | |
def postback_sent(req, invoice_id, data, tx=None): | |
return _create( | |
req, tx, POSTBACK_SENT, | |
invoice_id=invoice_id, | |
payload=data) | |
@db.atomic | |
def postback_failed(req, invoice_id, data, tx=None): | |
return _create( | |
req, tx, POSTBACK_FAILED, | |
invoice_id=invoice_id, | |
payload=data) | |
def _create(req, tx, typ, **kwargs): | |
r = LogRecord() | |
r.type = typ | |
r.created_at = datetime.now() | |
utm.fill(req, r) | |
if req.account_id: | |
r.actor_id = req.account_id | |
if req.device_id: | |
r.actor_device_id = req.device_id | |
if req.session_id: | |
r.actor_session_id = req.session_id | |
if req.ua: | |
r.actor_ua = req.ua | |
if req.ip: | |
r.actor_ip = req.ip | |
for key, value in kwargs.items(): | |
setattr(r, key, value) | |
tx.add(r) | |
tx.flush() | |
logger.debug('%s, r=%s, req=%s', typ, r, req) | |
return r | |
# Admin API | |
@db.fetch | |
def admin_query(req, query, tx=None): | |
return tables.query(query, tx) | |
@db.fetch | |
def admin_query_devices(req, query, tx=None): | |
return tables.query_devices(query, tx) | |
@db.fetch | |
def admin_query_by_id(req, record_id, tx=None): | |
return tables.record_by_id(record_id, tx) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from datetime import datetime | |
import sqlalchemy as sa | |
import sqlalchemy.orm as sa_orm | |
from payme import db, types | |
ADMIN_USERS_ADMIN_CREATED = 'admin/users/admin_created' | |
ADMIN_USERS_RECREATED = 'admin/users/recreated' | |
ADMIN_USERS_DELETED = 'admin/users/deleted' | |
ADMIN_USERS_ADDED_TO_ADMINS = 'admin/users/added_to_admins' | |
ADMIN_USERS_DELETED_FROM_ADMINS = 'admin/users/deleted_from_admins' | |
ADMIN_USERS_EMAIL_CONFIRMED = 'admin/users/email_confirmed' | |
ADMIN_USERS_PASSWORD_CHANGED = 'admin/users/password_changed' | |
ADMIN_ROLES_CREATED = 'admin/roles/created' | |
ADMIN_ROLES_UPDATED = 'admin/roles/updated' | |
ADMIN_ROLES_DELETED = 'admin/roles/deleted' | |
ADMIN_ROLES_MEMBER_ADDED = 'admin/roles/member_added' | |
ADMIN_ROLES_MEMBER_DELETED = 'admin/roles/member_deleted' | |
ACCOUNT_RECIPIENT_CREATED = 'accounts/recipient_created' | |
ACCOUNT_PAYER_CREATED = 'accounts/payer_created' | |
ALFABANK_TX_CREATED = 'alfabank/tx_created' | |
ALFABANK_TX_START_RESPONSE = 'alfabank/tx_start_response' | |
ALFABANK_TX_STARTED = 'alfabank/tx_started' | |
ALFABANK_TX_FAILED_TO_START = 'alfabank/tx_failed_to_start' | |
ALFABANK_TX_CONFIRMED = 'alfabank/tx_confirmed' | |
ALFABANK_TX_CONFIRM_REQUEST = 'alfabank/tx_confirm_request' | |
ALFABANK_TX_CONFIRM_FAILURE = 'alfabank/tx_confirm_failure' | |
ALFABANK_TX_COMPLETE_REQUEST = 'alfabank/tx_complete_request' | |
ALFABANK_TX_COMPLETE_RESPONSE = 'alfabank/tx_complete_response' | |
ALFABANK_TX_COMPLETED = 'alfabank/tx_completed' | |
ALFABANK_TX_COMPLETE_FAILURE = 'alfabank/tx_complete_failure' | |
ALFABANK_FEE_CALC_STARTED = 'alfabank/fee_calc_started' | |
ALFABANK_FEE_CALC_FAILED = 'alfabank/fee_calc_failed' | |
ALFABANK_FEE_CALC_RESPONSE = 'alfabank/fee_calc_response' | |
AUTH_TOKEN_CREATED = 'auth/token_created' | |
AUTH_SESSION_CREATED = 'auth/session_created' | |
CARDS_CREATED = 'cards/created' | |
DEVICES_CREATED = 'devices/created' | |
EMAILS_CREATED = 'emails/created' | |
EMAILS_CANCELLED = 'emails/cancelled' | |
EMAILS_FAILED = 'emails/failed' | |
EMAILS_SENT = 'emails/sent' | |
EMAILS_DELIVERED = 'emails/delivered' | |
EMAILS_OPENED = 'emails/opened' | |
INVOICES_CREATED = 'invoices/created' | |
INVOICES_SENT = 'invoices/sent' | |
INVOICES_CANCELLED = 'invoices/cancelled' | |
INVOICES_REFUSED = 'invoices/refused' | |
INVOICES_EXPIRED = 'invoices/expired' | |
INVOICES_REMINDED = 'invoices/reminded' | |
INVOICES_FAILED = 'invoices/failed' | |
INVOICES_PAID = 'invoices/paid' | |
POSTBACK_SENT = 'postback/sent' | |
POSTBACK_FAILED = 'postback/failed' | |
TITLES = { | |
# accounts | |
ACCOUNT_RECIPIENT_CREATED: 'Новый получатель', | |
ACCOUNT_PAYER_CREATED: 'Новый плательщик', | |
# alfabank_tx | |
ALFABANK_TX_CREATED: 'Транзакция создана', | |
ALFABANK_TX_START_RESPONSE: 'Получен ответ на начало транзакции', | |
ALFABANK_TX_STARTED: 'Транзакция начата', | |
ALFABANK_TX_FAILED_TO_START: 'Ошибка начала тразакции', | |
ALFABANK_TX_CONFIRM_REQUEST: 'Получен запрос на подтверждение транзакции', | |
ALFABANK_TX_CONFIRMED: 'Транзакция подтверждена', | |
ALFABANK_TX_CONFIRM_FAILURE: 'Ошибка подтверждения транзакции', | |
ALFABANK_TX_COMPLETE_REQUEST: 'Отправлен запрос на завершение транзакции', | |
ALFABANK_TX_COMPLETE_RESPONSE: 'Получен ответ на завершение транзакции', | |
ALFABANK_TX_COMPLETED: 'Транзакция завершена', | |
ALFABANK_TX_COMPLETE_FAILURE: 'Ошибка завершения транзакции', | |
# alfabank_fee | |
ALFABANK_FEE_CALC_STARTED: 'Начало расчета комиссии', | |
ALFABANK_FEE_CALC_FAILED: 'Ошибка расчета комиссии', | |
ALFABANK_FEE_CALC_RESPONSE: 'Комиссия рассчитана', | |
# auth | |
AUTH_TOKEN_CREATED: 'Авторизационный токен создан', | |
AUTH_SESSION_CREATED: 'Авторизационная сессия создана', | |
# cards | |
CARDS_CREATED: 'Карта создана', | |
# devices | |
DEVICES_CREATED: 'Устройство создано', | |
# emails | |
EMAILS_CREATED: 'Письмо создано', | |
EMAILS_CANCELLED: 'Письмо отменено', | |
EMAILS_FAILED: 'Ошибка доставки письма', | |
EMAILS_SENT: 'Письмо отправлено', | |
EMAILS_DELIVERED: 'Письмо доставлено', | |
EMAILS_OPENED: 'Письмо открыто', | |
# invoices | |
INVOICES_CREATED: 'Счет создан', | |
INVOICES_SENT: 'Счет отправлен плательщику', | |
INVOICES_CANCELLED: 'Счет отменен владельцем', | |
INVOICES_REFUSED: 'Плательщик отказался от оплаты счета', | |
INVOICES_EXPIRED: 'Истек срок оплаты счета', | |
INVOICES_FAILED: 'Ошибка счета', | |
INVOICES_PAID: 'Счет оплачен', | |
# postback | |
POSTBACK_SENT: 'Конверсия зарегистрирована', | |
POSTBACK_FAILED: 'Ошибка регистрации конверсии' | |
} | |
def type_title(t): | |
return TITLES.get(t, 'Неизвестное событие') | |
class LogRecord(db.Model): | |
__tablename__ = 'logs' | |
id = sa.Column(sa.BigInteger, primary_key=True) | |
type = sa.Column(sa.String) | |
created_at = sa.Column(sa.DateTime, default=datetime.now) | |
actor_id = sa.Column(types.UUID) | |
actor_device_id = sa.Column(types.UUID) | |
actor_session_id = sa.Column(types.UUID) | |
actor_ua = sa.Column(sa.String) | |
actor_ip = sa.Column(sa.String) | |
account_id = sa.Column(types.UUID, sa.ForeignKey('accounts.id')) | |
account = sa_orm.relation('Account', foreign_keys=account_id) | |
admin_role_id = sa.Column(types.UUID, sa.ForeignKey('admin_roles.id')) | |
admin_role = sa_orm.relation('Role', foreign_keys=admin_role_id) | |
admin_user_id = sa.Column(types.UUID, sa.ForeignKey('admin_user.id')) | |
admin_user = sa_orm.relation('User', foreign_keys=admin_user_id) | |
auth_token_id = sa.Column(types.UUID, sa.ForeignKey('auth_tokens.id')) | |
auth_token = sa_orm.relation('Token', foreign_keys=auth_token_id) | |
auth_session_id = sa.Column(types.UUID, sa.ForeignKey('auth_sessions.id')) | |
auth_session = sa_orm.relation('Session', foreign_keys=auth_session_id) | |
alfabank_tx_id = sa.Column(types.UUID, sa.ForeignKey('alfabank_transactions.id')) | |
alfabank_tx = sa_orm.relation('Transaction', foreign_keys=alfabank_tx_id) | |
card_id = sa.Column(types.UUID, sa.ForeignKey('cards.id')) | |
card = sa_orm.relation('Card', foreign_keys=card_id) | |
device_id = sa.Column(types.UUID, sa.ForeignKey('devices.id')) | |
device = sa_orm.relation('Device', foreign_keys=device_id) | |
email_id = sa.Column(types.UUID, sa.ForeignKey('emails.id')) | |
email = sa_orm.relation('Email', foreign_keys=email_id) | |
invoice_id = sa.Column(types.UUID, sa.ForeignKey('invoices.id')) | |
invoice = sa_orm.relation('Invoice', foreign_keys=invoice_id) | |
payload = sa.Column(sa.UnicodeText) | |
utm_source = sa.Column(sa.String) | |
utm_medium = sa.Column(sa.String) | |
utm_campaign = sa.Column(sa.String) | |
utm_content = sa.Column(sa.String) | |
utm_term = sa.Column(sa.String) | |
utm_referrer = sa.Column(sa.String) | |
utm_tid = sa.Column(sa.String) | |
def __str__(self): | |
cls = self.__class__.__name__ | |
attrs = ', '.join('%s=%s' % (k, v) for k, v in self.__dict__.items() if v) | |
return '<%s %s>' % (cls, attrs) | |
@property | |
def title(self): | |
return type_title(self.type) | |
class Query(types.PageQuery): | |
account_id = types.String | |
alfabank_tx_id = types.String | |
card_id = types.String | |
device_id = types.String | |
email_id = types.String | |
invoice_id = types.String | |
def __init__(self, page=1, per_page=1000, **kwargs): | |
super().__init__(page, per_page, **kwargs) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from .models import LogRecord | |
def record_by_id(record_id, tx): | |
return tx.query(LogRecord).get(record_id) | |
def query(query, tx): | |
if not query.is_valid: | |
return [] | |
q = tx.query(LogRecord) | |
if query.account_id: | |
q = q.filter(LogRecord.account_id == query.account_id) | |
if query.alfabank_tx_id: | |
q = q.filter(LogRecord.alfabank_tx_id == query.alfabank_tx_id) | |
if query.card_id: | |
q = q.filter(LogRecord.card_id == query.card_id) | |
if query.device_id: | |
q = q.filter(LogRecord.device_id == query.device_id) | |
if query.email_id: | |
q = q.filter(LogRecord.email_id == query.email_id) | |
if query.invoice_id: | |
q = q.filter(LogRecord.invoice_id == query.invoice_id) | |
return q.order_by(LogRecord.created_at.desc()) \ | |
.limit(query.limit).offset(query.offset).all() | |
def query_devices(query, tx): | |
from payme.devices.models import Device | |
if not query.is_valid: | |
return [] | |
q = tx.query(Device).join(LogRecord, LogRecord.actor_device_id == Device.id) | |
if query.account_id: | |
q = q.filter(LogRecord.account_id == query.account_id) | |
if query.alfabank_tx_id: | |
q = q.filter(LogRecord.alfabank_tx_id == query.alfabank_tx_id) | |
if query.card_id: | |
q = q.filter(LogRecord.card_id == query.card_id) | |
if query.device_id: | |
q = q.filter(LogRecord.device_id == query.device_id) | |
if query.email_id: | |
q = q.filter(LogRecord.email_id == query.email_id) | |
if query.invoice_id: | |
q = q.filter(LogRecord.invoice_id == query.invoice_id) | |
return q.distinct().order_by(Device.created_at.desc()) \ | |
.limit(query.limit).offset(query.offset).all() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment