From b40e3827b4939e0d6b5736a9a86a8e59b6ccbe64 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Wed, 13 Nov 2019 22:56:20 +0300 Subject: [PATCH] Add today time info --- assets/App.vue | 26 ++++++++++++++++++++++---- assets/helpers.js | 4 ++-- spec/entity_spec.cr | 12 ++++++++++++ spec/profile_spec.cr | 6 ++++++ src/dayoff.cr | 23 ++++++++++++++++++++++- src/dayoff/entities.cr | 28 +++++++++++----------------- src/dayoff/profile.cr | 22 ++++++++++++++++++++++ 7 files changed, 97 insertions(+), 24 deletions(-) create mode 100644 spec/entity_spec.cr diff --git a/assets/App.vue b/assets/App.vue index 04d21e4..cda5e32 100644 --- a/assets/App.vue +++ b/assets/App.vue @@ -7,6 +7,9 @@ Закончить Начать +
+ Сегодня {{ today_time }} +

Профиль: {{ profileId }}

@@ -21,12 +24,13 @@ export default { status: '', hours: 0, minutes: 0, + today: null, }; }, created() { this.profileId = h.extract_profile_id(); this.get_status(); - setInterval(() => this.get_status(), 30 * 1000); + setInterval(() => this.get_status(), 60 * 1000); }, computed: { time() { @@ -36,14 +40,19 @@ export default { isOvertime() { return this.status === 'overtime'; }, + today_time() { + const sign = this.today.status === 'overtime' ? '+' : ''; + return sign + this.today.hours + ':' + String(this.today.minutes).padStart(2, '0'); + } }, methods: { get_status() { h.get_status(this.profileId).then(data => { this.started = data.started; - this.status = data.status; - this.hours = data.hours; - this.minutes = data.minutes; + this.status = data.total.status; + this.hours = data.total.hours; + this.minutes = data.total.minutes; + this.today = data.today; }); }, start() { @@ -76,4 +85,13 @@ export default { .actions { font-size: 240%; } + +.today { + margin-top: 1em; + font-size: 200%; +} + +.profile-info { + margin-top: 2em; +} diff --git a/assets/helpers.js b/assets/helpers.js index 5df1f0b..db1fa37 100644 --- a/assets/helpers.js +++ b/assets/helpers.js @@ -7,7 +7,7 @@ function extract_profile_id() { const q = haystack.substring(haystack.indexOf('?') + 1, haystack.length); const query = qs.parse(q); const profile = query[PROFILE_QUERY] || ''; - console.log('PROFILE', query, profile); + // console.log('PROFILE', query, profile); return profile; } @@ -18,7 +18,7 @@ async function get_status(profileId) { method: 'GET', }); const data = await response.json(); - console.log('DATA', data); + // console.log('DATA', data); return data; } diff --git a/spec/entity_spec.cr b/spec/entity_spec.cr new file mode 100644 index 0000000..5b0683e --- /dev/null +++ b/spec/entity_spec.cr @@ -0,0 +1,12 @@ +require "./spec_helper" + +module Dayoff::Test + extend self + + describe "can check same date" do + planned_date = PlannedDate.new(t(1, 12), 8) + date = t(1, 20) + res = planned_date.same_date? date + res.should be_true + end +end diff --git a/spec/profile_spec.cr b/spec/profile_spec.cr index 5f0206c..e4fb326 100644 --- a/spec/profile_spec.cr +++ b/spec/profile_spec.cr @@ -94,5 +94,11 @@ module Dayoff::Test prof.finish finish_time end end + + it "can calc diff on concrete date" do + prof = create_profile + span = prof.date_status d(1) + span.total_hours.should eq -2 + end end end diff --git a/src/dayoff.cr b/src/dayoff.cr index 29a80dd..6198e16 100644 --- a/src/dayoff.cr +++ b/src/dayoff.cr @@ -6,6 +6,9 @@ base_path = ENV["BASE_PATH"] puts "Set storage base path: " + base_path +STATUS_UPTIME = "uptime" +STATUS_OVERTIME = "overtime" + app = Dayoff::App.new base_path add_handler CheckProfileHandler.new(app) @@ -14,6 +17,16 @@ def now Time.local(Time::Location.load("Europe/Moscow")) end +def date_status(profile, date) + span = profile.date_status date + { + date: date.to_s("%Y-%m-%d"), + status: span < Time::Span.zero ? STATUS_OVERTIME : STATUS_UPTIME, + hours: span.abs.total_hours.to_i32, + minutes: span.abs.minutes.to_i32, + } +end + post "/api/start" do |env| profile = app.profile Dayoff::ProfileId.new(env.get("profile_id").to_s) profile.start now @@ -29,7 +42,15 @@ end get "/api/status" do |env| profile = app.profile Dayoff::ProfileId.new(env.get("profile_id").to_s) rem_span = profile.remaining_time now - data = Dayoff::StatusResponse.new(profile.started?, rem_span) + data = { + started: profile.started?, + total: { + status: rem_span < Time::Span.zero ? STATUS_OVERTIME : STATUS_UPTIME, + hours: rem_span.abs.total_hours.to_i32, + minutes: rem_span.abs.minutes.to_i32, + }, + today: date_status(profile, now), + } env.response.content_type = "application/json" data.to_json end diff --git a/src/dayoff/entities.cr b/src/dayoff/entities.cr index 5d56904..441eb0f 100644 --- a/src/dayoff/entities.cr +++ b/src/dayoff/entities.cr @@ -26,6 +26,10 @@ module Dayoff def time_span : Time::Span Time::Span.new(hours: hours, minutes: 0, seconds: 0) end + + def same_date?(d : Time) : Bool + @date.date == d.date + end end class WorkRecord @@ -78,24 +82,14 @@ module Dayoff end end end - end - STATUS_UPTIME = "uptime" - STATUS_OVERTIME = "overtime" - - class StatusResponse - JSON.mapping( - started: Bool, - status: String, - hours: Int32, - minutes: Int32, - ) - - def initialize(@started : Bool, ts : Time::Span) - zero = Time::Span.zero - @status = ts < zero ? STATUS_OVERTIME : STATUS_UPTIME - @hours = ts.abs.total_hours.to_i32 - @minutes = ts.abs.minutes.to_i32 + def on_date(d : Time) : Time::Span + if @start.date == d.date + fin = @finish || d + fin - start + else + Time::Span.zero + end end end end diff --git a/src/dayoff/profile.cr b/src/dayoff/profile.cr index b7ae78d..4e8759b 100644 --- a/src/dayoff/profile.cr +++ b/src/dayoff/profile.cr @@ -71,6 +71,28 @@ module Dayoff planned - worked end + def date_status(d : Time) : Time::Span + planned = get_planned_hours_on_date d + worked = get_work_hours_on_date d + planned - worked + end + + private def get_planned_hours_on_date(d : Time) : Time::Span + @pdates.reduce(Time::Span.zero) do |acc, wd| + if wd.same_date? d + acc + wd.time_span + else + acc + end + end + end + + private def get_work_hours_on_date(d : Time) : Time::Span + @wrecords.reduce(Time::Span.zero) do |acc, wr| + acc + wr.on_date d + end + end + private def started_point @wrecords.find { |x| x.started? } end