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 ),
@@ -147,7 +144,7 @@ def create_fake_invoice(
147
144
"""
148
145
invoice_number = next (invoice_number_counter )
149
146
invoice = Invoice (
150
- number = invoice_number ,
147
+ number = str ( invoice_number ) ,
151
148
date = datetime .date .today (),
152
149
sent = fake .pybool (),
153
150
paid = fake .pybool (),
@@ -159,6 +156,7 @@ def create_fake_invoice(
159
156
number_of_items = fake .random_int (min = 1 , max = 5 )
160
157
for _ in range (number_of_items ):
161
158
unit = fake .random_element (elements = ("hours" , "days" ))
159
+ unit_price = 0
162
160
if unit == "hours" :
163
161
unit_price = abs (round (numpy .random .normal (50 , 20 ), 2 ))
164
162
elif unit == "days" :
@@ -169,12 +167,11 @@ def create_fake_invoice(
169
167
end_date = fake .date_this_decade (),
170
168
quantity = fake .random_int (min = 1 , max = 10 ),
171
169
unit = unit ,
172
- unit_price = unit_price ,
170
+ unit_price = Decimal ( unit_price ) ,
173
171
description = fake .sentence (),
174
- VAT_rate = vat_rate ,
172
+ VAT_rate = Decimal ( vat_rate ) ,
175
173
invoice = invoice ,
176
174
)
177
- assert invoice_item .invoice == invoice
178
175
179
176
try :
180
177
rendering .render_invoice (
@@ -231,7 +228,6 @@ def create_demo_user() -> User:
231
228
phone_number = "+55555555555" ,
232
229
VAT_number = "27B-6" ,
233
230
address = Address (
234
- name = "Harry Tuttle" ,
235
231
street = "Main Street" ,
236
232
number = "450" ,
237
233
city = "Somewhere" ,
@@ -248,6 +244,14 @@ def create_demo_user() -> User:
248
244
249
245
250
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
+
251
255
# create a new calendar
252
256
calendar = ics .Calendar ()
253
257
@@ -262,7 +266,7 @@ def create_fake_calendar(project_list: List[Project]) -> ics.Calendar:
262
266
for _ in range (random .randint (1 , 5 )):
263
267
# create a new event
264
268
event = ics .Event ()
265
- event .name = f"Meeting for # { project .tag } "
269
+ event .name = f"Meeting for { project .tag } "
266
270
267
271
# set the event's begin and end datetime
268
272
event .begin = random_datetime (month_ago , now )
@@ -273,16 +277,6 @@ def create_fake_calendar(project_list: List[Project]) -> ics.Calendar:
273
277
return calendar
274
278
275
279
276
- def random_datetime (start , end ):
277
- return start + timedelta (
278
- seconds = random .randint (0 , int ((end - start ).total_seconds ()))
279
- )
280
-
281
-
282
- def random_duration ():
283
- return timedelta (hours = random .randint (1 , 8 ))
284
-
285
-
286
280
def install_demo_data (
287
281
n_projects : int ,
288
282
db_path : str ,
@@ -336,7 +330,3 @@ def install_demo_data(
336
330
for project in projects :
337
331
session .add (project )
338
332
session .commit ()
339
-
340
-
341
- if __name__ == "__main__" :
342
- install_demo_data (n_projects = 10 )
0 commit comments