Skip to content

Commit e4e6907

Browse files
committed
Add Summary
1 parent a4c9f94 commit e4e6907

6 files changed

Lines changed: 198 additions & 1 deletion

File tree

backend/app.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,55 @@ def settings(f):
310310
return collection_settings
311311

312312

313+
@app.get("/api/summary")
314+
def summary(f):
315+
collection_summary = {}
316+
317+
file = f
318+
con = sqlite_connect(file)
319+
cur = con.cursor()
320+
321+
res = cur.execute("SELECT count(*) FROM coins")
322+
data = res.fetchall()
323+
collection_summary['total_count'] = data[0][0]
324+
325+
res = cur.execute("SELECT count(*) FROM coins WHERE status IN ('owned', 'ordered', 'sale', 'duplicate', 'replacement')")
326+
data = res.fetchall()
327+
collection_summary['count_owned'] = data[0][0]
328+
329+
res = cur.execute("SELECT count(*) FROM coins WHERE status='wish'")
330+
data = res.fetchall()
331+
collection_summary['count_wish'] = data[0][0]
332+
333+
res = cur.execute("SELECT count(*) FROM coins WHERE status='sold'")
334+
data = res.fetchall()
335+
collection_summary['count_sold'] = data[0][0]
336+
337+
res = cur.execute("SELECT count(*) FROM coins WHERE status='bidding'")
338+
data = res.fetchall()
339+
collection_summary['count_bidding'] = data[0][0]
340+
341+
res = cur.execute("SELECT count(*) FROM coins WHERE status='missing'")
342+
data = res.fetchall()
343+
collection_summary['count_missing'] = data[0][0]
344+
345+
res = cur.execute("SELECT SUM(totalpayprice) FROM coins WHERE status IN ('owned', 'ordered', 'sale', 'sold', 'missing', 'duplicate', 'replacement') AND totalpayprice<>'' AND totalpayprice IS NOT NULL")
346+
data = res.fetchall()
347+
collection_summary['paid'] = data[0][0]
348+
349+
res = cur.execute("SELECT SUM(payprice) FROM coins WHERE status IN ('owned', 'ordered', 'sale', 'sold', 'missing', 'duplicate', 'replacement') AND payprice<>'' AND payprice IS NOT NULL")
350+
data = res.fetchall()
351+
collection_summary['paid_without_commission'] = data[0][0]
352+
353+
res = cur.execute("SELECT paydate FROM coins WHERE status IN ('owned', 'ordered', 'sale', 'sold', 'missing', 'duplicate', 'replacement') AND paydate<>'' AND paydate IS NOT NULL ORDER BY paydate LIMIT 1")
354+
data = res.fetchall()
355+
collection_summary['first_purchase'] = data[0][0]
356+
357+
con.close()
358+
359+
return collection_summary
360+
361+
313362
app.mount("/", StaticFiles(directory="static", html=True), name="static")
314363

315364

frontend/src/App.vue

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import SettingsView from "@/components/SettingsView.vue";
1010
import AboutView from "@/components/AboutView.vue";
1111
import CoinView from "@/components/CoinView.vue";
1212
import ImagesView from "@/components/ImagesView.vue";
13+
import SummaryView from "@/components/SummaryView.vue";
1314
import { currentTheme } from "@/composables/useSettings";
1415
import PasswordDialog from '@/components/PasswordDialog.vue'
1516
import FileServerView from "@/components/FileServerView.vue";
@@ -124,6 +125,14 @@ const handleFileUpload = async (file) => {
124125
@click="router.push('/open'); drawer = false"
125126
:active="route.name === 'open'"
126127
></v-list-item>
128+
<v-list-item
129+
v-if="isOpened"
130+
prepend-icon="mdi-text-box-outline"
131+
:title="$t('title_summary')"
132+
value="summary"
133+
@click="router.push('/summary'); drawer = false"
134+
:active="route.name === 'summary'"
135+
></v-list-item>
127136
<v-list-item
128137
prepend-icon="mdi-cog"
129138
:title="$t('title_settings')"
@@ -151,6 +160,7 @@ const handleFileUpload = async (file) => {
151160
:settings="collectionSettings" :filters="collectionFilters"
152161
ref="coinListViewRef" />
153162
</KeepAlive>
163+
<SummaryView v-if="route.name === 'summary' && isOpened" />
154164
<CoinView v-if="route.name === 'coin' && isOpened"
155165
:settings="collectionSettings" />
156166
<ImagesView v-if="route.name === 'images' && isOpened" />
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<script setup>
2+
import {useService} from "@/composables/useService.js";
3+
import {onMounted, ref} from "vue";
4+
import i18n from "@/i18n/index.js";
5+
6+
const service = useService();
7+
8+
const summary = ref({})
9+
10+
onMounted(async () => {
11+
summary.value = await service.getSummary()
12+
})
13+
</script>
14+
15+
<template>
16+
<v-container>
17+
{{ i18n.global.t('Total count') }}: {{ summary.total_count }}<br>
18+
<template v-if="summary.count_owned">
19+
{{ i18n.global.t('Count owned') }}: {{ summary.count_owned }}<br>
20+
</template>
21+
<template v-if="summary.count_wish">
22+
{{ i18n.global.t('Count wish') }}: {{ summary.count_wish }}<br>
23+
</template>
24+
<template v-if="summary.count_sold">
25+
{{ i18n.global.t('Count sales') }}: {{ summary.count_sold }}<br>
26+
</template>
27+
<template v-if="summary.count_bidding">
28+
{{ i18n.global.t('Count biddings') }}: {{ summary.count_bidding }}<br>
29+
</template>
30+
<template v-if="summary.count_missing">
31+
{{ i18n.global.t('Count missing') }}: {{ summary.count_missing }}<br>
32+
</template>
33+
<template v-if="summary.paid">
34+
{{ i18n.global.t('Paid') }}: {{ i18n.global.n(summary.paid) }}
35+
<template v-if="summary.paid_without_commission">
36+
({{ i18n.global.t('commission') }}:
37+
{{ Math.round((summary.paid - summary.paid_without_commission) / summary.paid_without_commission * 100) }}%)
38+
</template>
39+
<br>
40+
<template v-if="summary.count_owned">
41+
{{ i18n.global.t('Average paid per item') }}:
42+
{{ i18n.global.n(summary.paid/summary.count_owned, { maximumFractionDigits: 2 }) }}
43+
<br>
44+
</template>
45+
</template>
46+
<template v-if="summary.first_purchase">
47+
{{ i18n.global.t('First purchase') }}: {{ i18n.global.d(summary.first_purchase) }}<br>
48+
</template>
49+
</v-container>
50+
</template>
51+
52+
<style scoped>
53+
54+
</style>

frontend/src/composables/useService.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,74 @@ export function useService(passwordDialogRef) {
511511
return infoFields.findIndex(element => element === field);
512512
}
513513

514+
const getSummary = async () => {
515+
if (connection_type === 'local')
516+
return getSummaryLocal();
517+
else if (connection_type === 'remote')
518+
return getSummaryRemote(connected_file);
519+
}
520+
521+
const getSummaryRemote = async (file) => {
522+
let summary= {};
523+
524+
await globalStatus.startLoading('Request');
525+
526+
try {
527+
const response = await api.get('/api/summary', {params: {f: file}})
528+
summary = response.data
529+
}
530+
catch (err) {
531+
globalStatus.error.value = err
532+
}
533+
finally {
534+
await globalStatus.finishLoading();
535+
}
536+
537+
return summary;
538+
}
539+
540+
const getSummaryLocal = async () => {
541+
let collection_summary = {};
542+
543+
let sql = "SELECT count(*) FROM coins"
544+
let results = await executeQuery(sql)
545+
collection_summary['total_count'] = results[0][0]
546+
547+
sql = "SELECT count(*) FROM coins WHERE status IN ('owned', 'ordered', 'sale', 'duplicate', 'replacement')"
548+
results = await executeQuery(sql)
549+
collection_summary['count_owned'] = results[0][0]
550+
551+
sql = "SELECT count(*) FROM coins WHERE status='wish'"
552+
results = await executeQuery(sql)
553+
collection_summary['count_wish'] = results[0][0]
554+
555+
sql = "SELECT count(*) FROM coins WHERE status='sold'"
556+
results = await executeQuery(sql)
557+
collection_summary['count_sold'] = results[0][0]
558+
559+
sql = "SELECT count(*) FROM coins WHERE status='bidding'"
560+
results = await executeQuery(sql)
561+
collection_summary['count_bidding'] = results[0][0]
562+
563+
sql = "SELECT count(*) FROM coins WHERE status='missing'"
564+
results = await executeQuery(sql)
565+
collection_summary['count_missing'] = results[0][0]
566+
567+
sql = "SELECT SUM(totalpayprice) FROM coins WHERE status IN ('owned', 'ordered', 'sale', 'sold', 'missing', 'duplicate', 'replacement') AND totalpayprice<>'' AND totalpayprice IS NOT NULL"
568+
results = await executeQuery(sql)
569+
collection_summary['paid'] = results[0][0]
570+
571+
sql = "SELECT SUM(payprice) FROM coins WHERE status IN ('owned', 'ordered', 'sale', 'sold', 'missing', 'duplicate', 'replacement') AND payprice<>'' AND payprice IS NOT NULL"
572+
results = await executeQuery(sql)
573+
collection_summary['paid_without_commission'] = results[0][0]
574+
575+
sql = "SELECT paydate FROM coins WHERE status IN ('owned', 'ordered', 'sale', 'sold', 'missing', 'duplicate', 'replacement') AND paydate<>'' AND paydate IS NOT NULL ORDER BY paydate LIMIT 1"
576+
results = await executeQuery(sql)
577+
collection_summary['first_purchase'] = results[0][0]
578+
579+
return collection_summary
580+
}
581+
514582
return {
515583
getServerFileList,
516584
openRemoteFile,
@@ -520,5 +588,6 @@ export function useService(passwordDialogRef) {
520588
getDetails,
521589
getPhotos,
522590
infoFieldIndex,
591+
getSummary,
523592
}
524593
}

frontend/src/i18n/en.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"uploading_safety_warranty": "Your file not will be uploaded to the internet. You can disable internet connection.",
33
"title_open": "Open",
4+
"title_summary": "Summary",
45
"title_settings": "Settings",
56
"title_about": "About",
67
"status_view_text": "Text",
@@ -34,5 +35,15 @@
3435
"replacement": "Replacement",
3536
"All": "All",
3637
"Sort by": "Sort by",
37-
"Search": "Search"
38+
"Search": "Search",
39+
"Total count": "Total count",
40+
"Count owned": "Count owned",
41+
"Count wish": "Count wish",
42+
"Count sales": "Count sales",
43+
"Count biddings": "Count biddings",
44+
"Count missing": "Count missing",
45+
"Paid": "Paid",
46+
"commission": "commission",
47+
"Average paid per item": "Average paid per item",
48+
"First purchase": "First purchase"
3849
}

frontend/src/router/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ const routes = [
2121
path: '/settings',
2222
name: 'settings',
2323
},
24+
{
25+
path: '/summary',
26+
name: 'summary',
27+
},
2428
{
2529
path: '/about',
2630
name: 'about',

0 commit comments

Comments
 (0)