Last active
June 19, 2019 15:21
-
-
Save hashlash/4ba03673c8c659e7a08087e57e8dd218 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
from abc import ABCMeta, abstractmethod | |
from collections import defaultdict | |
from typing import Iterable | |
from waste.models import WasteType | |
class TransactionUnit: | |
amount = 0 | |
unit = None | |
def __init__(self, amount, unit): | |
self.amount += amount | |
self.unit = self.unit or unit | |
def __add__(self, other): | |
return TransactionUnit(self.amount + other.amount, self.unit or other.unit) | |
class WasteTransactionUnit: | |
def __init__(self, waste: WasteType = None, | |
waste_unit_obj: TransactionUnit = None, | |
price_unit_obj: TransactionUnit = None, | |
data_dict: dict = None): | |
self._waste = waste | |
if isinstance(data_dict, dict): | |
self._waste_unit = TransactionUnit(data_dict['amount'], data_dict['unit']) | |
self._price_unit = TransactionUnit(data_dict['price'], data_dict['currency']) | |
elif (isinstance(waste_unit_obj, TransactionUnit) and | |
isinstance(price_unit_obj, TransactionUnit)): | |
self._waste_unit = waste_unit_obj | |
self._price_unit = price_unit_obj | |
else: | |
self._waste_unit = TransactionUnit(0, None) | |
self._price_unit = TransactionUnit(0, None) | |
def __add__(self, other): | |
return WasteTransactionUnit(waste=self.waste or other.waste, | |
waste_unit_obj=self.waste_unit + other.waste_unit, | |
price_unit_obj=self.price_unit + other.price_unit) | |
@property | |
def waste_unit(self): | |
return self._waste_unit | |
@property | |
def price_unit(self): | |
return self._price_unit | |
@property | |
def waste(self): | |
return self._waste | |
@property | |
def amount(self): | |
return self._waste_unit.amount | |
@property | |
def unit(self): | |
return self._waste_unit.unit | |
@property | |
def price(self): | |
return self._price_unit.amount | |
@property | |
def currency(self): | |
return self._price_unit.unit | |
class AbstractSummary(defaultdict, metaclass=ABCMeta): | |
def __init__(self, *args, **kwargs): | |
transactions = kwargs.pop('transactions', None) | |
super().__init__(*args, **kwargs) | |
if transactions: | |
for tx in transactions: | |
self.add_tx(tx) | |
def __getitem__(self, key): | |
try: | |
key_attr = getattr(self, key) | |
try: | |
return key_attr() | |
except TypeError: | |
return key_attr | |
except (TypeError, AttributeError): | |
return self.setdefault(key, self.default_factory()) | |
@abstractmethod | |
def add_tx(self, tx): | |
pass | |
@property | |
def total(self): | |
pass | |
class CategoryTransactionUnit(AbstractSummary): | |
def __init__(self, transactions: Iterable[WasteTransactionUnit] = None): | |
super().__init__(WasteTransactionUnit, transactions=transactions) | |
def add_tx(self, tx): | |
self[tx.waste] += tx | |
@property | |
def total(self): | |
return sum(self.values(), WasteTransactionUnit()) | |
class TransactionSummary(AbstractSummary): | |
def __init__(self, transactions: Iterable[WasteTransactionUnit] = None): | |
super().__init__(CategoryTransactionUnit, transactions=transactions) | |
def add_tx(self, tx): | |
self[tx.waste.category].add_tx(tx) | |
@property | |
def total(self): | |
return sum((tx.total for tx in self.values()), WasteTransactionUnit()) |
This file contains hidden or 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
def deposit_detail(request, date_str): | |
user = request.user | |
bsu = BankSampahUnit.objects.get(user=user) | |
date = parse_date(date_str) | |
tx_groups = TransactionDetail.objects \ | |
.filter(timestamp__date=date, account=bsu) \ | |
.exclude(obj=None).exclude(debit=None) \ | |
.values_list('transaction_id', flat=True) \ | |
.distinct() | |
transactions_dicts = TransactionDetail.objects \ | |
.filter(transaction_id__in=tx_groups) \ | |
.exclude(account=bsu).exclude(obj=None).exclude(credit=None) \ | |
.values('account', 'obj') \ | |
.annotate(amount=Sum('credit'), | |
unit=F('unit'), | |
price=Sum(F('credit') * F('curr_rate')), | |
currency=F('side__unit')) | |
nasabah_dict = {n.id: n for n in Nasabah.objects.filter(pk__in={tx['account'] for tx in transactions_dicts})} | |
waste_dict = {w.id: w for w in WasteType.objects.filter(pk__in={tx['obj'] for tx in transactions_dicts})} | |
transactions_units = [] | |
for tx in transactions_dicts: | |
tx['nasabah'] = nasabah_dict[tx['account']] | |
tx['waste'] = waste_dict[tx['obj']] | |
transactions_units.append(WasteTransactionUnit(waste=tx['waste'], data_dict=tx)) | |
summary = TransactionSummary(transactions_units) | |
summary_nasabah = defaultdict(TransactionSummary) | |
for tx in transactions_dicts: | |
summary_nasabah[tx['nasabah']].add_tx(WasteTransactionUnit(waste=tx['waste'], data_dict=tx)) | |
summary_nasabah.default_factory = None | |
return render(request, 'transaction/deposit/deposit-detail.html', { | |
'section': 'setoran', | |
'summary': summary, | |
'summary_nasabah': summary_nasabah, | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment