Skip to content

Commit

Permalink
Merge branch 'develop' into 'main'
Browse files Browse the repository at this point in the history
Develop

See merge request locker/api-core!396
  • Loading branch information
phuongntt-cystack committed Mar 15, 2024
2 parents 51a5d2d + 4a7a041 commit a594da9
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 22 deletions.
15 changes: 15 additions & 0 deletions locker_server/api/sub/resources/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,18 @@ def server_type(self, request, *args, **kwargs):
"name": app_info.name
})
return Response(status=status.HTTP_200_OK, data=data)

@action(methods=["get"], detail=False)
def list_enterprise_id(self, request, *args, **kwargs):
enterprise_ids = self.enterprise_service.list_enterprise_ids()
return Response(status=status.HTTP_200_OK, data=enterprise_ids)

@action(methods=["get"], detail=False)
def list_channel(self, request, *args, **kwargs):
user_channels = ["organic", "ads", "affiliate"]
return Response(status=status.HTTP_200_OK, data=user_channels)

@action(methods=["get"], detail=False)
def list_saas_market(self, request, *args, **kwargs):
saas_markets = self.payment_service.list_saas_market()
return Response(status=status.HTTP_200_OK, data=saas_markets)
3 changes: 3 additions & 0 deletions locker_server/api/sub/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
urlpatterns += [
url(r'^resources/countries$', LONG_TIME_CACHE(views.ResourcePwdViewSet.as_view({'get': 'countries'}))),
url(r'^resources/server_type$', views.ResourcePwdViewSet.as_view({'get': 'server_type'})),
url(r'^resources/enterprise_ids$', views.ResourcePwdViewSet.as_view({'get': 'list_enterprise_id'})),
url(r'^resources/channels$', views.ResourcePwdViewSet.as_view({'get': 'list_channel'})),
url(r'^resources/saas_markets$', views.ResourcePwdViewSet.as_view({'get': 'list_saas_market'})),
url(r'^resources/cystack_platform/pm/plans$', views.ResourcePwdViewSet.as_view({'get': 'plans'})),
url(r'^resources/cystack_platform/pm/enterprise/plans$',
views.ResourcePwdViewSet.as_view({'get': 'enterprise_plans'})),
Expand Down
2 changes: 0 additions & 2 deletions locker_server/api/v1_0/payments/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,6 @@ def statistic_income(self, request, *args, **kwargs):
"from": from_param,
"to": to_param,
"duration": duration_param,
"platform": query_params.get("platform"),
"status": query_params.get("status"),
"plan": query_params.get("plan"),
"utm_source": query_params.get("utm_source"),
Expand All @@ -591,7 +590,6 @@ def statistic_amount(self, request, *args, **kwargs):
"from": from_param,
"to": to_param,
"duration": duration_param,
"platform": query_params.get("platform"),
"status": query_params.get("status"),
"plan": query_params.get("plan"),
"utm_source": query_params.get("utm_source"),
Expand Down
3 changes: 3 additions & 0 deletions locker_server/api_orm/repositories/enterprise_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def list_enterprises(self, **filters) -> List[Enterprise]:
for enterprise_orm in enterprises_orm
]

def list_enterprise_ids(self) -> List[int]:
return list(set(EnterpriseORM.objects.all().values_list("id", flat=True)))

def list_user_enterprises(self, user_id: int, **filter_params) -> List[Enterprise]:
status_param = filter_params.get("status")
if status_param is not None:
Expand Down
63 changes: 43 additions & 20 deletions locker_server/api_orm/repositories/payment_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from django.db.models.functions import TruncYear

from locker_server.api_orm.model_parsers.wrapper import get_model_parser
from locker_server.api_orm.models import CustomerORM
from locker_server.api_orm.models import CustomerORM, SaasMarketORM
from locker_server.api_orm.models.wrapper import get_payment_model, get_promo_code_model, get_user_model, \
get_user_plan_model, get_plan_model
from locker_server.api_orm.repositories import UserORMRepository
Expand Down Expand Up @@ -98,11 +98,10 @@ def _get_current_plan_orm(user_id: int) -> PMUserPlanORM:
def list_payments_orm(cls, **filters) -> List[PaymentORM]:
from_param = filters.get("from")
to_param = filters.get("to")
platform_param = filters.get("platform", "") # CHPlay,Stripe,ChPlay, Markets
status_param = filters.get("status") # success,failed,pending
plan_param = filters.get("plan") # premium, lifetime,family,enterprise
channel_param = filters.get("channel") # organic,ads, affiliate
source_param = filters.get("source") # stacksocial, dealmirror, saasmantra
source_param = filters.get("source") # stacksocial, dealmirror, saasmantra, stripe, ios, android
payment_method_param = filters.get("payment_method")
user_id_param = filters.get("user_id")
enterprise_id_param = filters.get("enterprise_id")
Expand All @@ -122,20 +121,7 @@ def list_payments_orm(cls, **filters) -> List[PaymentORM]:
if channel_param:
user_ids = UserORMRepository.search_from_cystack_id(**{"utm_source": channel_param}).get("ids", [])
payments_orm = payments_orm.filter(user_id__in=user_ids)
if platform_param:
platform_param = platform_param.lower()
if platform_param == "stripe":
payments_orm = payments_orm.filter(stripe_invoice_id__isnull=False)
elif platform_param == "ios":
payments_orm = payments_orm.filter(
Q(metadata__contains="ios") & Q(mobile_invoice_id__isnull=False)
)
elif platform_param == "android":
payments_orm = payments_orm.filter(
Q(metadata__contains="android") &
Q(mobile_invoice_id__isnull=False)

)
if payment_method_param:
payments_orm = payments_orm.filter(payment_method=payment_method_param)
if user_id_param:
Expand All @@ -144,7 +130,20 @@ def list_payments_orm(cls, **filters) -> List[PaymentORM]:
payments_orm = payments_orm.filter(enterprise_id=enterprise_id_param)
if source_param:
source_param = source_param.lower()
payments_orm = payments_orm.filter(saas_market__icontains=source_param)
if source_param == "stripe":
payments_orm = payments_orm.filter(stripe_invoice_id__isnull=False)
elif source_param == "ios":
payments_orm = payments_orm.filter(
Q(metadata__contains="ios") & Q(mobile_invoice_id__isnull=False)
)
elif source_param == "android":
payments_orm = payments_orm.filter(
Q(metadata__contains="android") &
Q(mobile_invoice_id__isnull=False)

)
else:
payments_orm = payments_orm.filter(saas_market__icontains=source_param)
payments_orm = payments_orm.select_related('user')
payments_orm = payments_orm.order_by("-created_time")
return payments_orm
Expand All @@ -157,6 +156,9 @@ def list_all_invoices(self, **filter_params) -> List[Payment]:
payments.append(ModelParser.payment_parser().parse_payment(payment_orm=payment_orm))
return payments

def list_saas_market(self) -> List[str]:
return list(set(SaasMarketORM.objects.all().values_list("id", flat=True)))

def list_invoices_by_user(self, user_id: int, **filter_params) -> List[Payment]:
payments_orm = PaymentORM.objects.filter(user_id=user_id).order_by('-created_time')
from_param = filter_params.get("from")
Expand Down Expand Up @@ -207,7 +209,7 @@ def statistic_income(self, **filters) -> Dict:
payment_id__startswith="LK"
)
success_payments_orm = payments_orm.filter(
status="paid"
Q(status="paid") & Q(transaction_type="Payment")
)

# statistic income by duration
Expand Down Expand Up @@ -240,13 +242,24 @@ def statistic_income(self, **filters) -> Dict:
payments_orm_by_status = payments_orm.values("status", "currency").annotate(
total_price=Sum('total_price')
).order_by('status', 'currency')
refunds_orm = payments_orm.filter(
Q(status="paid") & Q(transaction_type="Refund")
).values("currency").annotate(
total_price=Sum('total_price')
).order_by('currency')
payment_by_status_statistic = {}
for item in payments_orm_by_status:
status_dict = payment_by_status_statistic.get(item.get("status")) or {}
status_dict.update({
item.get('currency'): item.get("total_price")
})
payment_by_status_statistic[item.get("status")] = status_dict
payment_by_status_statistic.update({
"refund": {
item.get("currency"): item.get("total_price")
for item in refunds_orm
}
})
total_payment_orm = payments_orm.values("currency").annotate(
total_price=Sum(F('total_price'))
).order_by("currency")
Expand Down Expand Up @@ -286,7 +299,7 @@ def statistic_amount(self, **filters) -> Dict:
payment_id__startswith="LK"
)
success_payments_orm = payments_orm.filter(
status="paid",
Q(status="paid") & Q(transaction_type="Payment")
)

# statistic volume by duration
Expand Down Expand Up @@ -314,7 +327,11 @@ def statistic_amount(self, **filters) -> Dict:
total_volume = success_payments_orm.values("currency").annotate(
volume=Count('total_price')
).order_by("currency")

refunds_orm = payments_orm.filter(
Q(status="paid") & Q(transaction_type="Refund")
).values("currency").annotate(
volume=Count('total_price')
).order_by("currency")
# Statistic by status
payments_orm_by_status = payments_orm.values("status", "currency").annotate(
volume=Count('total_price')
Expand All @@ -326,6 +343,12 @@ def statistic_amount(self, **filters) -> Dict:
item.get('currency'): item.get("volume")
})
payment_by_status_statistic[item.get("status")] = status_dict
payment_by_status_statistic.update({
"refund": {
item.get("currency"): item.get("volume")
for item in refunds_orm
}
})
total_payment_orm = payments_orm.values("currency").annotate(
volume=Count('total_price')
).order_by("currency")
Expand Down
4 changes: 4 additions & 0 deletions locker_server/core/repositories/enterprise_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ class EnterpriseRepository(ABC):
def list_enterprises(self, **filters) -> List[Enterprise]:
pass

@abstractmethod
def list_enterprise_ids(self) -> List[int]:
pass

@abstractmethod
def list_user_enterprises(self, user_id: int, **filter_params) -> List[Enterprise]:
pass
Expand Down
4 changes: 4 additions & 0 deletions locker_server/core/repositories/payment_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ class PaymentRepository(ABC):
def list_all_invoices(self, **filter_params) -> List[Payment]:
pass

@abstractmethod
def list_saas_market(self) -> List[str]:
pass

@abstractmethod
def list_invoices_by_user(self, user_id: int, **filter_params) -> List[Payment]:
pass
Expand Down
3 changes: 3 additions & 0 deletions locker_server/core/services/enterprise_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ def __init__(self, enterprise_repository: EnterpriseRepository,
def list_policies_by_user(self, user_id: int) -> List[EnterprisePolicy]:
return self.enterprise_policy_repository.list_policies_by_user(user_id=user_id)

def list_enterprise_ids(self) -> List[str]:
return self.enterprise_repository.list_enterprise_ids()

def get_enterprise_by_id(self, enterprise_id: str) -> Optional[Enterprise]:
enterprise = self.enterprise_repository.get_enterprise_by_id(
enterprise_id=enterprise_id
Expand Down
3 changes: 3 additions & 0 deletions locker_server/core/services/payment_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ def allow_upgrade_enterprise_trial(self, user_id: int):
def list_all_invoices(self, **filter_params) -> List[Payment]:
return self.payment_repository.list_all_invoices(**filter_params)

def list_saas_market(self) -> List[str]:
return self.payment_repository.list_saas_market()

def list_user_invoices(self, user_id: int, **filter_params) -> List[Payment]:
return self.payment_repository.list_invoices_by_user(user_id=user_id, **filter_params)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ def send(self, **kwargs):
destinations = get_destinations(kwargs.get("user_ids") or [])
else:
destinations = kwargs.get("destinations", [])
if not destinations:
return
# Normalize the mail data in kwargs
detail_data = self.normalize_data(**kwargs)
# Normalize mail message
Expand Down

0 comments on commit a594da9

Please sign in to comment.