from typing import Dict, Collection from camisatoshi_wordpress_reports.constants import order_keys, custom_meta_data_keys from camisatoshi_wordpress_reports.utils import safe_zero_division class Order: def __init__(self, raw_data: Dict): self.raw_data = raw_data def __getitem__(self, item): return self.raw_data[item] @property def meta_data_entries(self): return { meta_data_entry["key"]: meta_data_entry["value"] for meta_data_entry in self.raw_data[order_keys.meta_data] } def units_of_sku(self, sku: str) -> int: units = 0 for line in self[order_keys.line_items]: if line[order_keys.line_item_keys.sku] == sku: units += line[order_keys.line_item_keys.quantity] return units def sales_of_sku(self, sku: str) -> float: sales = 0 for line in self[order_keys.line_items]: if line[order_keys.line_item_keys.sku] == sku: sales += float(line[order_keys.line_item_keys.total]) return sales def sats_received_for_sku(self, sku: str) -> float: total_order_eur = float(self[order_keys.total]) eur_of_sku = self.sales_of_sku(sku) monetary_weight_of_sku_in_order = safe_zero_division(eur_of_sku, total_order_eur) total_order_sats_received = float( self.meta_data_entries[custom_meta_data_keys.sats_received] ) sats_received_for_sku = ( monetary_weight_of_sku_in_order * total_order_sats_received ) return sats_received_for_sku def contains_sku(self, sku: str) -> bool: for item in self[order_keys.line_items]: if item[order_keys.line_item_keys.sku] == sku: return True return False def contains_meta_data_entry(self, meta_data_entry_key: str) -> bool: if meta_data_entry_key in self.meta_data_entries.keys(): return True return False def is_settled_with_um(self): is_settled = self.meta_data_entries.get( custom_meta_data_keys.is_settled_with_um, None ) return bool(is_settled) @classmethod def from_api_response(cls, raw_data) -> "Order": return Order(raw_data) class Orders: def __init__(self, orders: Collection[Order]): self._orders = orders def __len__(self): return len(self._orders) def __iter__(self): self._index = 0 return self def __next__(self): if self._index < len(self._orders): next_order = self._orders[self._index] self._index += 1 return next_order raise StopIteration def filter_orders_by_sku(self, sku: str) -> "Orders": filtered_orders = [] for order in self: if order.contains_sku(sku): filtered_orders.append(order) return Orders(filtered_orders) def filter_orders_without_sats_received(self) -> "Orders": orders_without_sats_received = [] for order in self: if not order.contains_meta_data_entry(custom_meta_data_keys.sats_received): orders_without_sats_received.append(order) continue return Orders(orders_without_sats_received) def filter_unsettled_orders(self) -> "Orders": unsettled_orders = [] for order in self: if not order.is_settled_with_um(): unsettled_orders.append(order) return Orders(unsettled_orders)