Coverage for hledger_lots/avg_info.py: 64%

59 statements  

« prev     ^ index     » next       coverage.py v7.2.3, created at 2023-05-05 00:05 -0300

1from datetime import datetime 

2from typing import Optional, Tuple 

3 

4from .avg import get_avg_cost 

5from .info import AllInfo, Info, LotsInfo 

6from .lib import dt_list2table 

7 

8 

9class AvgInfo(Info): 

10 def __init__( 

11 self, 

12 journals: Tuple[str, ...], 

13 commodity: str, 

14 check: bool, 

15 no_desc: Optional[str] = None, 

16 ): 

17 super().__init__(journals, commodity, no_desc) 

18 self.check = check 

19 self.avg_lots = get_avg_cost(self.txns, self.check) 

20 self.table = dt_list2table(self.avg_lots) 

21 

22 def get_info(self): 

23 if len(self.txns) == 0: 

24 return 

25 

26 commodity = self.commodity 

27 cur = self.txns[0].base_cur 

28 qtty = self.avg_lots[-1].total_qtty 

29 amount = self.avg_lots[-1].total_amount 

30 avg_cost = self.avg_lots[-1].avg_cost 

31 last_buy_date = datetime.strptime(self.avg_lots[-1].date, "%Y-%m-%d").date() 

32 xirr = self.get_lots_xirr(last_buy_date) 

33 

34 if self.market_price and self.market_date and xirr: 

35 market_price_str = f"{self.market_price:,.4f}" 

36 market_amount = self.market_price * qtty 

37 market_amount_str = f"{market_amount:,.2f}" 

38 market_profit = market_amount - amount 

39 market_profit_str = f"{market_profit:,.2f}" 

40 market_date = self.market_date.strftime("%Y-%m-%d") 

41 xirr_str = f"{xirr:,.4f}%" 

42 else: 

43 market_amount_str = "" 

44 market_profit_str = "" 

45 market_date = "" 

46 market_price_str = "" 

47 xirr_str = "" 

48 

49 return LotsInfo( 

50 comm=commodity, 

51 cur=cur, 

52 qtty=str(qtty), 

53 amount=f"{amount:,.2f}", 

54 avg_cost=f"{avg_cost:,.4f}", 

55 mkt_price=market_price_str, 

56 mkt_amount=market_amount_str, 

57 mkt_profit=market_profit_str, 

58 mkt_date=market_date, 

59 xirr=xirr_str, 

60 ) 

61 

62 @property 

63 def info_txt(self): 

64 info = self.get_info() 

65 if not info: 

66 return f"No transaction for {self.commodity}" 

67 

68 return self.get_info_txt(info) 

69 

70 

71class AllAvgInfo(AllInfo): 

72 def __init__(self, journals: Tuple[str, ...], no_desc: str, check: bool): 

73 super().__init__(journals, no_desc) 

74 self.check = check 

75 

76 def get_info(self, commodity: str): 

77 avg_obj = AvgInfo(self.journals, commodity, self.check) 

78 if len(avg_obj.txns) == 0: 

79 return 

80 else: 

81 return avg_obj.get_info() 

82 

83 @property 

84 def infos(self): 

85 infos = [self.get_info(com) for com in self.commodities] 

86 infos = [info for info in infos if info] 

87 return infos 

88 

89 def infos_table(self, output_format: str): 

90 return self.get_infos_table(self.infos, output_format) 

91 

92 def infos_csv(self): 

93 return self.get_infos_csv(self.infos)