1
- from typing import List , Optional , Callable
1
+ from typing import Callable , List , Optional
2
2
3
+ import datetime
3
4
import random
5
+ from datetime import date , timedelta
4
6
from pathlib import Path
5
- from tuttle .calendar import Calendar , ICSCalendar
7
+ from decimal import Decimal
8
+
6
9
import faker
7
- import random
8
- import datetime
9
- from datetime import timedelta , date
10
10
import ics
11
- from sqlmodel import Field , SQLModel , create_engine , Session , select
11
+ import numpy
12
12
import sqlalchemy
13
13
from loguru import logger
14
- import numpy
14
+ from sqlmodel import Field , Session , SQLModel , create_engine , select
15
15
16
+ from tuttle import rendering
17
+ from tuttle .calendar import Calendar , ICSCalendar
16
18
from tuttle .model import (
17
19
Address ,
18
- Contact ,
20
+ BankAccount ,
19
21
Client ,
20
- Project ,
22
+ Contact ,
21
23
Contract ,
22
- TimeUnit ,
23
24
Cycle ,
24
- User ,
25
- BankAccount ,
26
25
Invoice ,
27
26
InvoiceItem ,
27
+ Project ,
28
+ TimeUnit ,
29
+ User ,
28
30
)
29
- from tuttle import rendering
30
31
31
32
32
33
def create_fake_contact (
33
34
fake : faker .Faker ,
34
35
):
35
- try :
36
- street_line , city_line = fake .address ().splitlines ()
37
- a = Address (
38
- id = id ,
39
- street = street_line .split (" " )[0 ],
40
- number = street_line .split (" " )[1 ],
41
- city = city_line .split (" " )[1 ],
42
- postal_code = city_line .split (" " )[0 ],
43
- country = fake .country (),
44
- )
45
- first_name , last_name = fake .name ().split (" " , 1 )
46
- contact = Contact (
47
- id = id ,
48
- first_name = first_name ,
49
- last_name = last_name ,
50
- email = fake .email (),
51
- company = fake .company (),
52
- address_id = a .id ,
53
- address = a ,
54
- )
55
- return contact
56
- except Exception as ex :
57
- logger .error (ex )
58
- logger .error (f"Failed to create fake contact, trying again" )
59
- return create_fake_contact (fake )
36
+
37
+ split_address_lines = fake .address ().splitlines ()
38
+ street_line = split_address_lines [0 ]
39
+ city_line = split_address_lines [1 ]
40
+ a = Address (
41
+ street = street_line ,
42
+ number = city_line ,
43
+ city = city_line .split (" " )[1 ],
44
+ postal_code = city_line .split (" " )[0 ],
45
+ country = fake .country (),
46
+ )
47
+ first_name , last_name = fake .name ().split (" " , 1 )
48
+ contact = Contact (
49
+ first_name = first_name ,
50
+ last_name = last_name ,
51
+ email = fake .email (),
52
+ company = fake .company (),
53
+ address_id = a .id ,
54
+ address = a ,
55
+ )
56
+ return contact
60
57
61
58
62
59
def create_fake_client (
63
60
invoicing_contact : Contact ,
64
61
fake : faker .Faker ,
65
62
):
66
63
client = Client (
67
- id = id ,
68
64
name = fake .company (),
69
65
invoicing_contact = invoicing_contact ,
70
66
)
67
+ assert client .invoicing_contact is not None
71
68
return client
72
69
73
70
@@ -92,7 +89,7 @@ def create_fake_contract(
92
89
start_date = fake .date_this_year (after_today = True ),
93
90
rate = rate ,
94
91
currency = "EUR" , # TODO: Use actual currency
95
- VAT_rate = round (random .uniform (0.05 , 0.2 ), 2 ),
92
+ VAT_rate = Decimal ( round (random .uniform (0.05 , 0.2 ), 2 ) ),
96
93
unit = unit ,
97
94
units_per_workday = random .randint (1 , 12 ),
98
95
volume = fake .random_int (1 , 1000 ),
@@ -106,11 +103,12 @@ def create_fake_project(
106
103
fake : faker .Faker ,
107
104
):
108
105
project_title = fake .bs ()
106
+ project_tag = f"#{ '-' .join (project_title .split (' ' )[:2 ]).lower ()} "
107
+
109
108
project = Project (
110
109
title = project_title ,
111
- tag = "-" . join ( project_title . split ( " " )[: 2 ]). lower () ,
110
+ tag = project_tag ,
112
111
description = fake .paragraph (nb_sentences = 2 ),
113
- unique_tag = project_title .split (" " )[0 ].lower (),
114
112
is_completed = fake .pybool (),
115
113
start_date = datetime .date .today (),
116
114
end_date = datetime .date .today () + datetime .timedelta (days = 80 ),
@@ -146,7 +144,7 @@ def create_fake_invoice(
146
144
"""
147
145
invoice_number = next (invoice_number_counter )
148
146
invoice = Invoice (
149
- number = invoice_number ,
147
+ number = str ( invoice_number ) ,
150
148
date = datetime .date .today (),
151
149
sent = fake .pybool (),
152
150
paid = fake .pybool (),
@@ -158,6 +156,7 @@ def create_fake_invoice(
158
156
number_of_items = fake .random_int (min = 1 , max = 5 )
159
157
for _ in range (number_of_items ):
160
158
unit = fake .random_element (elements = ("hours" , "days" ))
159
+ unit_price = 0
161
160
if unit == "hours" :
162
161
unit_price = abs (round (numpy .random .normal (50 , 20 ), 2 ))
163
162
elif unit == "days" :
@@ -168,12 +167,11 @@ def create_fake_invoice(
168
167
end_date = fake .date_this_decade (),
169
168
quantity = fake .random_int (min = 1 , max = 10 ),
170
169
unit = unit ,
171
- unit_price = unit_price ,
170
+ unit_price = Decimal ( unit_price ) ,
172
171
description = fake .sentence (),
173
- VAT_rate = vat_rate ,
172
+ VAT_rate = Decimal ( vat_rate ) ,
174
173
invoice = invoice ,
175
174
)
176
- assert invoice_item .invoice == invoice
177
175
178
176
try :
179
177
rendering .render_invoice (
@@ -230,7 +228,6 @@ def create_demo_user() -> User:
230
228
phone_number = "+55555555555" ,
231
229
VAT_number = "27B-6" ,
232
230
address = Address (
233
- name = "Harry Tuttle" ,
234
231
street = "Main Street" ,
235
232
number = "450" ,
236
233
city = "Somewhere" ,
@@ -247,6 +244,14 @@ def create_demo_user() -> User:
247
244
248
245
249
246
def create_fake_calendar (project_list : List [Project ]) -> ics .Calendar :
247
+ def random_datetime (start , end ):
248
+ return start + timedelta (
249
+ seconds = random .randint (0 , int ((end - start ).total_seconds ()))
250
+ )
251
+
252
+ def random_duration ():
253
+ return timedelta (hours = random .randint (1 , 8 ))
254
+
250
255
# create a new calendar
251
256
calendar = ics .Calendar ()
252
257
@@ -261,7 +266,7 @@ def create_fake_calendar(project_list: List[Project]) -> ics.Calendar:
261
266
for _ in range (random .randint (1 , 5 )):
262
267
# create a new event
263
268
event = ics .Event ()
264
- event .name = f"Meeting for # { project .tag } "
269
+ event .name = f"Meeting for { project .tag } "
265
270
266
271
# set the event's begin and end datetime
267
272
event .begin = random_datetime (month_ago , now )
@@ -272,16 +277,6 @@ def create_fake_calendar(project_list: List[Project]) -> ics.Calendar:
272
277
return calendar
273
278
274
279
275
- def random_datetime (start , end ):
276
- return start + timedelta (
277
- seconds = random .randint (0 , int ((end - start ).total_seconds ()))
278
- )
279
-
280
-
281
- def random_duration ():
282
- return timedelta (hours = random .randint (1 , 8 ))
283
-
284
-
285
280
def install_demo_data (
286
281
n_projects : int ,
287
282
db_path : str ,
@@ -335,7 +330,3 @@ def install_demo_data(
335
330
for project in projects :
336
331
session .add (project )
337
332
session .commit ()
338
-
339
-
340
- if __name__ == "__main__" :
341
- install_demo_data (n_projects = 10 )
0 commit comments