Skip to content

Commit 1d099b7

Browse files
committed
refactor: Contracts Editor
1 parent 11adc83 commit 1d099b7

File tree

5 files changed

+101
-144
lines changed

5 files changed

+101
-144
lines changed

app/contracts/view.py

+85-104
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
from enum import Enum
44

55
from flet import (
6-
ButtonStyle,
76
Card,
87
Column,
98
Container,
10-
ElevatedButton,
119
Icon,
1210
IconButton,
1311
ListTile,
@@ -26,12 +24,6 @@
2624
from core import utils, views
2725
from core.abstractions import DialogHandler, TView, TViewParams
2826
from core.intent_result import IntentResult
29-
from core.models import (
30-
get_cycle_from_value,
31-
get_cycle_values_as_list,
32-
get_time_unit_from_value,
33-
get_time_unit_values_as_list,
34-
)
3527
from res import colors, dimens, fonts, res_utils
3628

3729
from tuttle.model import Client, Contract, CONTRACT_DEFAULT_VAT_RATE
@@ -223,52 +215,7 @@ def __init__(
223215
self.clients_map = {}
224216
self.contacts_map = {}
225217
self.available_currencies = []
226-
self.title = ""
227218
self.client = None
228-
self.rate = ""
229-
self.currency = ""
230-
self.vat_rate = ""
231-
self.time_unit: TimeUnit = None
232-
self.unit_pw = ""
233-
self.volume = ""
234-
self.term_of_payment = ""
235-
self.billing_cycle: Cycle = None
236-
237-
def on_title_changed(self, e):
238-
"""Called when the title of the contract is changed"""
239-
self.title = e.control.value
240-
241-
def on_rate_changed(self, e):
242-
"""Called when the rate of the contract is changed"""
243-
self.rate = e.control.value
244-
245-
def on_currency_changed(self, e):
246-
"""Called when the currency of the contract is changed"""
247-
self.currency = e.control.value
248-
249-
def on_volume_changed(self, e):
250-
"""Called when the volume of the contract is changed"""
251-
self.volume = e.control.value
252-
253-
def on_term_of_payment_changed(self, e):
254-
"""Called when the term of payment of the contract is changed"""
255-
self.term_of_payment = e.control.value
256-
257-
def on_upw_changed(self, e):
258-
"""Called when the unit pw of the contract is changed"""
259-
self.unit_pw = e.control.value
260-
261-
def on_vat_rate_changed(self, e):
262-
"""Called when the vat rate of the contract is changed"""
263-
self.vat_rate = e.control.value
264-
265-
def on_unit_selected(self, e):
266-
"""Called when the unit of the contract is changed""" ""
267-
self.time_unit = get_time_unit_from_value(e.control.value)
268-
269-
def on_billing_cycle_selected(self, e):
270-
"""Called when the billing cycle of the contract is changed"""
271-
self.billing_cycle = get_cycle_from_value(e.control.value)
272219

273220
def clear_ui_field_errors(self, e):
274221
"""Clears all the errors in the ui form fields"""
@@ -311,7 +258,7 @@ def load_contract_for_update(self):
311258
if not result.was_intent_successful or not result.data:
312259
self.show_snack(result.error_msg, is_error=True)
313260
self.old_contract_if_editing = result.data
314-
self.display_with_contract_info()
261+
self.display_contract_info()
315262

316263
def load_currencies(self):
317264
"""Loads the available currencies into a dropdown"""
@@ -348,16 +295,14 @@ def get_client_dropdown_item(self, client_id):
348295
if client_id not in self.clients_map:
349296
return ""
350297
# prefix client name with a key {client_id}
351-
return f"#{client_id} {self.clients_map[client_id].name}"
298+
return f"{client_id}. {self.clients_map[client_id].name}"
352299

353300
def on_client_selected(self, e):
354301
# parse selected value to extract id
355302
selected = e.control.value
356303
_id = ""
357304
for c in selected:
358-
if c == "#":
359-
continue
360-
if c == " ":
305+
if c == ".":
361306
break
362307
_id = _id + c
363308

@@ -403,9 +348,9 @@ def on_client_set_from_pop_up(self, client):
403348
self.show_snack(result.error_msg, True)
404349
self.update_self()
405350

406-
def display_with_contract_info(self):
351+
def display_contract_info(self):
407352
"""initialize form fields with data from old contract"""
408-
self.title_ui_field.value = self.title = self.old_contract_if_editing.title
353+
self.title_ui_field.value = self.old_contract_if_editing.title
409354
signature_date = self.old_contract_if_editing.signature_date
410355
self.signature_date_ui_field.set_date(signature_date)
411356
start_date = self.old_contract_if_editing.start_date
@@ -417,41 +362,81 @@ def display_with_contract_info(self):
417362
self.clients_ui_field.update_value(
418363
self.get_client_dropdown_item(self.client.id)
419364
)
420-
self.rate_ui_field.value = self.rate = self.old_contract_if_editing.rate
421-
self.currency = self.old_contract_if_editing.currency
422-
self.currency_ui_field.update_value(self.currency)
423-
self.vat_rate_ui_field.value = (
424-
self.vat_rate
425-
) = self.old_contract_if_editing.VAT_rate
426-
427-
self.time_unit = self.old_contract_if_editing.unit
428-
if self.time_unit:
429-
self.units_ui_field.update_value(self.time_unit.value)
430-
self.unit_PW_ui_field.value = (
431-
self.unit_pw
432-
) = self.old_contract_if_editing.units_per_workday
433-
self.volume_ui_field.value = self.volume = self.old_contract_if_editing.volume
365+
self.rate_ui_field.value = self.old_contract_if_editing.rate
366+
self.currency_ui_field.update_value(self.old_contract_if_editing.currency)
367+
self.vat_rate_ui_field.value = self.old_contract_if_editing.VAT_rate
368+
if self.old_contract_if_editing.unit:
369+
self.time_unit_field.update_value(self.old_contract_if_editing.unit.name)
370+
self.unit_PW_ui_field.value = self.old_contract_if_editing.units_per_workday
371+
self.volume_ui_field.value = self.old_contract_if_editing.volume
434372
self.term_of_payment_ui_field.value = (
435-
self.term_of_payment
436-
) = self.old_contract_if_editing.term_of_payment
437-
self.billing_cycle = self.old_contract_if_editing.billing_cycle
438-
if self.billing_cycle:
439-
self.billing_cycle_ui_field.update_value(self.billing_cycle.value)
373+
self.old_contract_if_editing.term_of_payment
374+
)
375+
if self.old_contract_if_editing.billing_cycle:
376+
self.billing_cycle_ui_field.update_value(
377+
self.old_contract_if_editing.billing_cycle.name
378+
)
440379
self.form_title_ui_field.value = "Edit Contract"
441380
self.submit_btn.text = "Save changes"
442381

443382
def on_save(self, e):
444383
"""Called when the edit / save button is clicked"""
445-
if not self.title:
384+
# get data from form fields
385+
title = self.title_ui_field.value
386+
rate = self.rate_ui_field.value
387+
vat_rate = self.vat_rate_ui_field.value
388+
unit_pw = self.unit_PW_ui_field.value
389+
volume = self.volume_ui_field.value
390+
term_of_payment = self.term_of_payment_ui_field.value
391+
currency = self.currency_ui_field.value
392+
time_unit_str = self.time_unit_field.value
393+
try:
394+
time_unit = TimeUnit[time_unit_str]
395+
except KeyError:
396+
time_unit = None
397+
398+
billing_cycle_str = self.billing_cycle_ui_field.value
399+
try:
400+
billing_cycle = Cycle[billing_cycle_str]
401+
except KeyError:
402+
billing_cycle = None
403+
404+
# check for missing fields
405+
if not title:
446406
self.title_ui_field.error_text = "Contract title is required"
447407
self.update_self()
448408
return # error occurred, stop here
449409

410+
if not currency:
411+
self.currency_ui_field.update_error_txt("Please specify the currency")
412+
self.update_self()
413+
return
414+
415+
if not rate:
416+
self.rate_ui_field.error_text = "Rate of enumeration is required"
417+
self.update_self()
418+
return
419+
420+
if not time_unit:
421+
self.time_unit_field.update_error_txt("Unit of time tracked is required")
422+
self.update_self()
423+
return
424+
425+
if not unit_pw:
426+
self.unit_PW_ui_field.error_text = "Units per workday is required"
427+
self.update_self()
428+
return
429+
450430
if self.client is None:
451431
self.clients_ui_field.update_error_txt("Please select a client")
452432
self.update_self()
453433
return # error occurred, stop here
454434

435+
if not billing_cycle:
436+
self.billing_cycle_ui_field.update_error_txt("Billing cycle is required")
437+
self.update_self()
438+
return
439+
455440
signatureDate = self.signature_date_ui_field.get_date()
456441
if signatureDate is None:
457442
self.show_snack("Please specify the signature date", True)
@@ -473,24 +458,26 @@ def on_save(self, e):
473458
)
474459
return # error occurred, stop here
475460

476-
if not self.vat_rate:
477-
self.vat_rate = CONTRACT_DEFAULT_VAT_RATE
461+
vat_rate = self.vat_rate_ui_field.value
462+
if not vat_rate:
463+
vat_rate = CONTRACT_DEFAULT_VAT_RATE
478464

479465
self.toggle_progress(is_on_going_action=True)
466+
480467
result: IntentResult = self.intent.save_contract(
481-
title=self.title,
468+
title=title,
482469
signature_date=signatureDate,
483470
start_date=startDate,
484471
end_date=endDate,
485472
client=self.client,
486-
rate=self.rate,
487-
currency=self.currency,
488-
VAT_rate=self.vat_rate,
489-
unit=self.time_unit,
490-
units_per_workday=self.unit_pw,
491-
volume=self.volume,
492-
term_of_payment=self.term_of_payment,
493-
billing_cycle=self.billing_cycle,
473+
rate=rate,
474+
currency=currency,
475+
VAT_rate=vat_rate,
476+
unit=time_unit,
477+
units_per_workday=unit_pw,
478+
volume=volume,
479+
term_of_payment=term_of_payment,
480+
billing_cycle=billing_cycle,
494481
contract=self.old_contract_if_editing,
495482
)
496483
success_msg = (
@@ -511,47 +498,40 @@ def build(self):
511498
self.title_ui_field = views.TTextField(
512499
label="Title",
513500
hint="Short description of the contract.",
514-
on_change=self.on_title_changed,
515501
on_focus=self.clear_ui_field_errors,
516502
)
517503
self.rate_ui_field = views.TTextField(
518504
label="Rate",
519505
hint="Rate of remuneration",
520-
on_change=self.on_rate_changed,
521506
on_focus=self.clear_ui_field_errors,
522507
keyboard_type=utils.KEYBOARD_NUMBER,
523508
)
524509
self.currency_ui_field = views.TDropDown(
525510
label="Currency",
526511
hint="Payment currency",
527-
on_change=self.on_currency_changed,
528512
items=self.available_currencies,
529513
)
530514
self.vat_rate_ui_field = views.TTextField(
531515
label="VAT rate",
532516
hint=f"VAT rate applied to the contractual rate. default is {CONTRACT_DEFAULT_VAT_RATE}",
533-
on_change=self.on_vat_rate_changed,
534517
on_focus=self.clear_ui_field_errors,
535518
keyboard_type=utils.KEYBOARD_NUMBER,
536519
)
537520
self.unit_PW_ui_field = views.TTextField(
538521
label="Units per workday",
539522
hint="How many units (e.g. hours) constitute a whole work day?",
540-
on_change=self.on_upw_changed,
541523
on_focus=self.clear_ui_field_errors,
542524
keyboard_type=utils.KEYBOARD_NUMBER,
543525
)
544526
self.volume_ui_field = views.TTextField(
545527
label="Volume (optional)",
546528
hint="Number of time units agreed on",
547-
on_change=self.on_volume_changed,
548529
on_focus=self.clear_ui_field_errors,
549530
keyboard_type=utils.KEYBOARD_NUMBER,
550531
)
551532
self.term_of_payment_ui_field = views.TTextField(
552533
label="Term of payment (optional)",
553534
hint="How many days after receipt of invoice this invoice is due.",
554-
on_change=self.on_term_of_payment_changed,
555535
on_focus=self.clear_ui_field_errors,
556536
keyboard_type=utils.KEYBOARD_NUMBER,
557537
)
@@ -560,15 +540,13 @@ def build(self):
560540
on_change=self.on_client_selected,
561541
items=self.get_clients_names_as_list(),
562542
)
563-
self.units_ui_field = views.TDropDown(
543+
self.time_unit_field = views.TDropDown(
564544
label="Unit of time tracked.",
565-
on_change=self.on_unit_selected,
566-
items=get_time_unit_values_as_list(),
545+
items=[str(t) for t in TimeUnit],
567546
)
568547
self.billing_cycle_ui_field = views.TDropDown(
569548
label="Billing Cycle",
570-
on_change=self.on_billing_cycle_selected,
571-
items=get_cycle_values_as_list(),
549+
items=[str(c) for c in Cycle],
572550
)
573551
self.signature_date_ui_field = views.DateSelector(label="Signed on")
574552
self.start_date_ui_field = views.DateSelector(label="Valid from")
@@ -594,7 +572,7 @@ def build(self):
594572
self.currency_ui_field,
595573
self.rate_ui_field,
596574
self.term_of_payment_ui_field,
597-
self.units_ui_field,
575+
self.time_unit_field,
598576
self.unit_PW_ui_field,
599577
self.vat_rate_ui_field,
600578
self.volume_ui_field,
@@ -806,6 +784,9 @@ def display_contract_data(self):
806784
_status = self.contract.get_status(default="")
807785
if _status:
808786
self.status_control.value = f"Status {_status}"
787+
self.status_control.visible = True
788+
else:
789+
self.status_control.visible = False
809790
self.billing_cycle_control.value = (
810791
self.contract.billing_cycle.value if self.contract.billing_cycle else ""
811792
)

app/core/models.py

-38
Original file line numberDiff line numberDiff line change
@@ -19,48 +19,10 @@
1919
from tuttle.dev import deprecated
2020

2121

22-
@deprecated("syntactic salt: use list(Enum) instead")
23-
def get_cycle_values_as_list():
24-
values = []
25-
for c in Cycle:
26-
values.append(str(c))
27-
return values
2822

2923

30-
@deprecated("square wheel reinvention antipattern: use Enum[value] instead")
31-
def get_cycle_from_value(value: str) -> Optional[Cycle]:
32-
if value == Cycle.daily.value:
33-
return Cycle.daily
34-
elif value == Cycle.hourly.value:
35-
return Cycle.hourly
36-
elif value == Cycle.weekly.value:
37-
return Cycle.weekly
38-
elif value == Cycle.monthly.value:
39-
return Cycle.monthly
40-
elif value == Cycle.yearly.value:
41-
return Cycle.yearly
42-
else:
43-
return None
4424

4525

46-
@deprecated("syntactic salt: use list(Enum) instead")
47-
def get_time_unit_values_as_list():
48-
values = []
49-
for t in TimeUnit:
50-
values.append(str(t))
51-
return values
52-
53-
54-
@deprecated("square wheel reinvention antipattern: use Enum[value] instead")
55-
def get_time_unit_from_value(value: str) -> Optional[TimeUnit]:
56-
if value == TimeUnit.day.value:
57-
return TimeUnit.day
58-
elif value == TimeUnit.hour.value:
59-
return TimeUnit.hour
60-
elif value == TimeUnit.minute.value:
61-
return TimeUnit.minute
62-
else:
63-
return None
6426

6527

6628
@dataclass

0 commit comments

Comments
 (0)