1+ use crate :: config:: Config ;
2+ use crate :: core:: logic:: Core ;
13use crate :: db:: pool:: DbPool ;
24use crate :: db:: queries:: { insert_event, load_events_by_date, load_pair_by_index} ;
35use crate :: errors:: { AppError , AppResult } ;
46use crate :: models:: event:: { Event , EventExtras } ;
57use crate :: models:: event_type:: EventType ;
68use crate :: models:: location:: Location ;
79use crate :: ui:: messages:: success;
8- use chrono:: { NaiveDate , NaiveTime } ;
10+ use chrono:: { NaiveDate , NaiveTime , Timelike } ;
911use rusqlite:: params;
1012
1113/// High-level business logic for the `add` command.
@@ -20,9 +22,42 @@ fn upsert_event(conn: &rusqlite::Connection, ev: &Event) -> AppResult<()> {
2022 Ok ( ( ) )
2123}
2224
25+ fn build_event_cli (
26+ date : NaiveDate ,
27+ time : NaiveTime ,
28+ kind : EventType ,
29+ location : Location ,
30+ event_extras : EventExtras ,
31+ ) -> Event {
32+ Event :: new ( 0 , date, time, kind, location, event_extras)
33+ }
34+
35+ fn extras_cli ( lunch : Option < i32 > , work_gap : bool ) -> EventExtras {
36+ EventExtras {
37+ lunch,
38+ work_gap,
39+ source : Some ( "cli" . to_string ( ) ) ,
40+ meta : None ,
41+ ..Default :: default ( )
42+ }
43+ }
44+
45+ fn upsert_event_time (
46+ slot : & mut Option < Event > ,
47+ date : NaiveDate ,
48+ time : NaiveTime ,
49+ kind : EventType ,
50+ location : Location ,
51+ extras : EventExtras ,
52+ ) {
53+ let e = slot. get_or_insert_with ( || build_event_cli ( date, time, kind, location, extras) ) ;
54+ e. time = time;
55+ }
56+
2357impl AddLogic {
2458 #[ allow( clippy:: too_many_arguments) ]
2559 pub fn apply (
60+ cfg : & Config ,
2661 pool : & mut DbPool ,
2762 date : NaiveDate ,
2863 position : Location ,
@@ -66,48 +101,29 @@ impl AddLogic {
66101 }
67102 }
68103
104+ // IN time
69105 // IN time
70106 if let Some ( start_time) = start {
71- if let Some ( ref mut e) = ev_in {
72- e. time = start_time;
73- } else {
74- ev_in = Some ( Event :: new (
75- 0 ,
76- date,
77- start_time,
78- EventType :: In ,
79- pos_final,
80- EventExtras {
81- lunch, // if user passed --lunch in edit mode, keep it on IN creation
82- work_gap : false ,
83- source : Some ( "cli" . to_string ( ) ) ,
84- meta : None ,
85- ..Default :: default ( )
86- } ,
87- ) ) ;
88- }
107+ upsert_event_time (
108+ & mut ev_in,
109+ date,
110+ start_time,
111+ EventType :: In ,
112+ pos_final,
113+ extras_cli ( lunch, false ) ,
114+ ) ;
89115 }
90116
91117 // OUT time
92118 if let Some ( end_time) = end {
93- if let Some ( ref mut e) = ev_out {
94- e. time = end_time;
95- } else {
96- ev_out = Some ( Event :: new (
97- 0 ,
98- date,
99- end_time,
100- EventType :: Out ,
101- pos_final,
102- EventExtras {
103- lunch : Some ( 0 ) ,
104- work_gap : false ,
105- source : Some ( "cli" . to_string ( ) ) ,
106- meta : None ,
107- ..Default :: default ( )
108- } ,
109- ) ) ;
110- }
119+ upsert_event_time (
120+ & mut ev_out,
121+ date,
122+ end_time,
123+ EventType :: Out ,
124+ pos_final,
125+ extras_cli ( Some ( 0 ) , false ) , // se vuoi preservare la tua semantica OUT default
126+ ) ;
111127 }
112128
113129 // LUNCH (applies to OUT; coherent with your current model)
@@ -188,19 +204,12 @@ impl AddLogic {
188204 let holiday_time = NaiveTime :: from_hms_opt ( 0 , 0 , 0 )
189205 . ok_or_else ( || AppError :: Other ( "Invalid holiday time sentinel." . into ( ) ) ) ?;
190206
191- let ev_holiday = Event :: new (
192- 0 ,
207+ let ev_holiday = build_event_cli (
193208 date,
194209 holiday_time,
195- EventType :: In , // sentinel kind
210+ EventType :: In ,
196211 pos_final,
197- EventExtras {
198- lunch : Some ( 0 ) ,
199- work_gap : false ,
200- source : Some ( "cli" . to_string ( ) ) ,
201- meta : None ,
202- ..Default :: default ( )
203- } ,
212+ extras_cli ( lunch, false ) ,
204213 ) ;
205214
206215 insert_event ( & pool. conn , & ev_holiday) ?;
@@ -254,25 +263,31 @@ impl AddLogic {
254263 if let Some ( start_time) = start
255264 && end. is_none ( )
256265 {
257- let ev_in = Event :: new (
258- 0 ,
266+ let ev_in = build_event_cli (
259267 date,
260268 start_time,
261269 EventType :: In ,
262270 pos_final,
263- EventExtras {
264- lunch : Some ( lunch_val) ,
265- work_gap : false ,
266- source : Some ( "cli" . to_string ( ) ) ,
267- meta : None ,
268- ..Default :: default ( )
269- } ,
271+ extras_cli ( lunch, false ) ,
270272 ) ;
271273
272274 insert_event ( & pool. conn , & ev_in) ?;
273275 crate :: db:: queries:: recalc_pairs_for_date ( & mut pool. conn , & date) ?;
274276
275- success ( format ! ( "Added IN at {} on {}." , start_time, date_str) ) ;
277+ // --- Compute TGT (same logic as list: uses summary.expected) ---
278+ let events_after = load_events_by_date ( pool, & date) ?;
279+ let summary = Core :: build_daily_summary ( & events_after, cfg) ;
280+
281+ let tgt_time = start_time + chrono:: Duration :: minutes ( summary. expected ) ;
282+
283+ // Usa helper esistente: minuti da mezzanotte -> "HH:MM"
284+ let tgt_mins = ( tgt_time. hour ( ) as i64 ) * 60 + ( tgt_time. minute ( ) as i64 ) ;
285+ let tgt_str = crate :: utils:: time:: format_minutes ( tgt_mins) ;
286+
287+ success ( format ! (
288+ "✅ Added IN at {} on {}. TGT => {}" ,
289+ start_time, date_str, tgt_str
290+ ) ) ;
276291 return Ok ( ( ) ) ;
277292 }
278293
@@ -302,19 +317,12 @@ impl AddLogic {
302317 last_in. location
303318 } ;
304319
305- let ev_out = Event :: new (
306- 0 ,
320+ let ev_out = build_event_cli (
307321 date,
308322 end_time,
309323 EventType :: Out ,
310324 out_position,
311- EventExtras {
312- lunch : Some ( lunch_val) ,
313- work_gap : wg,
314- source : Some ( "cli" . to_string ( ) ) ,
315- meta : None ,
316- ..Default :: default ( )
317- } ,
325+ extras_cli ( lunch, false ) ,
318326 ) ;
319327
320328 insert_event ( & pool. conn , & ev_out) ?;
@@ -333,34 +341,20 @@ impl AddLogic {
333341 return Err ( AppError :: InvalidArgs ( "END must be later than IN." . into ( ) ) ) ;
334342 }
335343
336- let ev_in = Event :: new (
337- 0 ,
344+ let ev_in = build_event_cli (
338345 date,
339346 start_time,
340347 EventType :: In ,
341348 pos_final,
342- EventExtras {
343- lunch : Some ( lunch_val) ,
344- work_gap : false ,
345- source : Some ( "cli" . to_string ( ) ) ,
346- meta : None ,
347- ..Default :: default ( )
348- } ,
349+ extras_cli ( lunch, false ) ,
349350 ) ;
350351
351- let ev_out = Event :: new (
352- 0 ,
352+ let ev_out = build_event_cli (
353353 date,
354354 end_time,
355355 EventType :: Out ,
356356 pos_final,
357- EventExtras {
358- lunch : Some ( 0 ) ,
359- work_gap : wg,
360- source : Some ( "cli" . to_string ( ) ) ,
361- meta : None ,
362- ..Default :: default ( )
363- } ,
357+ extras_cli ( lunch, false ) ,
364358 ) ;
365359
366360 insert_event ( & pool. conn , & ev_in) ?;
0 commit comments