Add Mollie settlement information to admin panel
This commit is contained in:
149
svelte/src/admin_panel/MollieSettlement.svelte
Normal file
149
svelte/src/admin_panel/MollieSettlement.svelte
Normal file
@@ -0,0 +1,149 @@
|
||||
<script>
|
||||
import { onMount } from "svelte";
|
||||
import { formatDate } from "../util/Formatting.svelte";
|
||||
import LoadingIndicator from "../util/LoadingIndicator.svelte";
|
||||
import Euro from "../util/Euro.svelte";
|
||||
|
||||
export let settlement = {}
|
||||
let loading = true
|
||||
let response = {}
|
||||
let payments = []
|
||||
|
||||
let per_country = {}
|
||||
let totals = {
|
||||
count: 0,
|
||||
vat: 0,
|
||||
amount: 0,
|
||||
}
|
||||
|
||||
const get_payments = async () => {
|
||||
loading = true;
|
||||
try {
|
||||
const req = await fetch(
|
||||
window.api_endpoint+"/admin/mollie_settlements/" + settlement.id + "/payments?limit=250"
|
||||
);
|
||||
if(req.status >= 400) {
|
||||
throw new Error(req.text());
|
||||
}
|
||||
response = await req.json()
|
||||
payments = response._embedded.payments
|
||||
|
||||
payments.forEach(row => {
|
||||
if (!per_country[row.metadata.country]) {
|
||||
per_country[row.metadata.country] = {
|
||||
vat: 0,
|
||||
amount: 0,
|
||||
count: 0,
|
||||
vat_fraction: row.metadata.vat_fraction,
|
||||
}
|
||||
}
|
||||
per_country[row.metadata.country].vat += row.metadata.vat
|
||||
per_country[row.metadata.country].amount += row.metadata.amount
|
||||
per_country[row.metadata.country].count++
|
||||
|
||||
totals.vat += row.metadata.vat
|
||||
totals.amount += row.metadata.amount
|
||||
totals.count++
|
||||
})
|
||||
|
||||
// Sort the countries. Don't ask me how it works
|
||||
per_country = Object.keys(per_country).sort().reduce(
|
||||
(obj, key) => {
|
||||
obj[key] = per_country[key]
|
||||
return obj
|
||||
},
|
||||
{}
|
||||
)
|
||||
|
||||
console.log(per_country)
|
||||
} catch (err) {
|
||||
alert(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMount(get_payments);
|
||||
</script>
|
||||
|
||||
<LoadingIndicator loading={loading}/>
|
||||
|
||||
<h3>Accounting information</h3>
|
||||
|
||||
{#if per_country.NL}
|
||||
<ul>
|
||||
<li>NL excluding VAT: <Euro amount={per_country.NL.amount}/></li>
|
||||
<li>NL VAT: <Euro amount={per_country.NL.vat}/></li>
|
||||
<li>OSS VAT: <Euro amount={totals.vat-per_country.NL.vat}/></li>
|
||||
<li>Remainder: <Euro amount={(settlement.amount.value*1e6)-per_country.NL.amount-(totals.vat-per_country.NL.vat)}/></li>
|
||||
</ul>
|
||||
{/if}
|
||||
|
||||
|
||||
<h3>Taxes per country</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Country</td>
|
||||
<td>Payments</td>
|
||||
<td>Amount</td>
|
||||
<td>VAT</td>
|
||||
<td>VAT%</td>
|
||||
<td>Total</td>
|
||||
</tr>
|
||||
{#each Object.entries(per_country) as [country, row]}
|
||||
<tr>
|
||||
<td>{country}</td>
|
||||
<td>{row.count}</td>
|
||||
<td><Euro amount={row.amount}/></td>
|
||||
<td><Euro amount={row.vat}/></td>
|
||||
<td>{row.vat_fraction*100}%</td>
|
||||
<td><Euro amount={row.vat+row.amount}/></td>
|
||||
</tr>
|
||||
{/each}
|
||||
|
||||
<tr>
|
||||
<td>Total</td>
|
||||
<td>{totals.count}</td>
|
||||
<td><Euro amount={totals.amount}/></td>
|
||||
<td><Euro amount={totals.vat}/></td>
|
||||
<td></td>
|
||||
<td><Euro amount={totals.vat+totals.amount}/></td>
|
||||
</tr>
|
||||
{#if per_country.NL}
|
||||
<tr>
|
||||
<td>Total - NL</td>
|
||||
<td>{totals.count - per_country.NL.count}</td>
|
||||
<td><Euro amount={totals.amount-per_country.NL.amount}/></td>
|
||||
<td><Euro amount={totals.vat-per_country.NL.vat}/></td>
|
||||
<td></td>
|
||||
<td><Euro amount={(totals.vat-per_country.NL.vat)+(totals.amount-per_country.NL.amount)}/></td>
|
||||
</tr>
|
||||
{/if}
|
||||
</table>
|
||||
|
||||
|
||||
<h3>All payments ({payments.length})</h3>
|
||||
<div class="table_scroll">
|
||||
<table>
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td>Created</td>
|
||||
<td>Status</td>
|
||||
<td>Country</td>
|
||||
<td>Amount</td>
|
||||
<td>VAT</td>
|
||||
<td>Total</td>
|
||||
</tr>
|
||||
{#each payments as row (row.id)}
|
||||
<tr>
|
||||
<td><a href={row._links.dashboard.href} target="_blank">{row.id}</a></td>
|
||||
<td>{formatDate(row.createdAt, true, true, false)}</td>
|
||||
<td>{row.status}</td>
|
||||
<td>{row.metadata.country}</td>
|
||||
<td><Euro amount={row.metadata.amount}/></td>
|
||||
<td><Euro amount={row.metadata.vat}/></td>
|
||||
<td><Euro amount={row.amount.value*1e6}/></td>
|
||||
</tr>
|
||||
{/each}
|
||||
</table>
|
||||
</div>
|
76
svelte/src/admin_panel/MollieSettlements.svelte
Normal file
76
svelte/src/admin_panel/MollieSettlements.svelte
Normal file
@@ -0,0 +1,76 @@
|
||||
<script>
|
||||
import { onMount } from "svelte";
|
||||
import { formatDate } from "../util/Formatting.svelte";
|
||||
import Expandable from "../util/Expandable.svelte";
|
||||
import LoadingIndicator from "../util/LoadingIndicator.svelte";
|
||||
import Euro from "../util/Euro.svelte";
|
||||
import MollieSettlement from "./MollieSettlement.svelte";
|
||||
|
||||
let loading = true
|
||||
let response = {}
|
||||
let settlements = []
|
||||
|
||||
const get_settlements = async () => {
|
||||
loading = true;
|
||||
try {
|
||||
const req = await fetch(window.api_endpoint+"/admin/mollie_settlements?limit=250");
|
||||
if(req.status >= 400) {
|
||||
throw new Error(req.text());
|
||||
}
|
||||
response = await req.json()
|
||||
settlements = response._embedded.settlements
|
||||
} catch (err) {
|
||||
alert(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMount(get_settlements);
|
||||
</script>
|
||||
|
||||
<LoadingIndicator loading={loading}/>
|
||||
|
||||
<section>
|
||||
{#each settlements as row (row.id)}
|
||||
<Expandable click_expand>
|
||||
<div slot="header" class="header">
|
||||
<div class="title">{row.id}</div>
|
||||
<div class="stats">
|
||||
Date<br/>
|
||||
{formatDate(row.createdAt, false, false, false)}
|
||||
</div>
|
||||
<div class="stats">
|
||||
Amount<br/>
|
||||
<Euro amount={row.amount.value*1e6}/>
|
||||
</div>
|
||||
<div class="stats">
|
||||
Status<br/>
|
||||
{row.status}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<MollieSettlement settlement={row}/>
|
||||
</Expandable>
|
||||
{/each}
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
.title {
|
||||
flex: 1 1 auto;
|
||||
align-self: center;
|
||||
word-break: break-all;
|
||||
padding-left: 8px;
|
||||
}
|
||||
.stats {
|
||||
flex: 0 0 auto;
|
||||
padding: 0 4px;
|
||||
border-left: 1px solid var(--separator);
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
@@ -6,6 +6,7 @@ import BlockFiles from "./BlockFiles.svelte";
|
||||
import TabMenu from "../util/TabMenu.svelte";
|
||||
import UserManagement from "./UserManagement.svelte";
|
||||
import EmailReporters from "./EmailReporters.svelte";
|
||||
import MollieSettlements from "./MollieSettlements.svelte";
|
||||
|
||||
let pages = [
|
||||
{
|
||||
@@ -38,6 +39,11 @@ let pages = [
|
||||
title: "User Management",
|
||||
icon: "person",
|
||||
component: UserManagement,
|
||||
}, {
|
||||
path: "/admin/mollie_settlements",
|
||||
title: "Mollie Settlements",
|
||||
icon: "paid",
|
||||
component: MollieSettlements,
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
@@ -195,10 +195,11 @@ func New(r *httprouter.Router, prefix string, conf Config) (wc *WebController) {
|
||||
{GET, "admin" /* */, wc.serveTemplate("admin", handlerOpts{Auth: true})},
|
||||
{GET, "admin/status" /* */, wc.serveTemplate("admin", handlerOpts{Auth: true})},
|
||||
{GET, "admin/block_files" /* */, wc.serveTemplate("admin", handlerOpts{Auth: true})},
|
||||
{GET, "admin/email_reporters" /**/, wc.serveTemplate("admin", handlerOpts{Auth: true})},
|
||||
{GET, "admin/email_reporters" /* */, wc.serveTemplate("admin", handlerOpts{Auth: true})},
|
||||
{GET, "admin/abuse_reports" /* */, wc.serveTemplate("admin", handlerOpts{Auth: true})},
|
||||
{GET, "admin/ip_bans" /* */, wc.serveTemplate("admin", handlerOpts{Auth: true})},
|
||||
{GET, "admin/user_management" /**/, wc.serveTemplate("admin", handlerOpts{Auth: true})},
|
||||
{GET, "admin/user_management" /* */, wc.serveTemplate("admin", handlerOpts{Auth: true})},
|
||||
{GET, "admin/mollie_settlements" /**/, wc.serveTemplate("admin", handlerOpts{Auth: true})},
|
||||
{GET, "admin/globals" /* */, wc.serveForm(wc.adminGlobalsForm, handlerOpts{Auth: true})},
|
||||
{PST, "admin/globals" /* */, wc.serveForm(wc.adminGlobalsForm, handlerOpts{Auth: true})},
|
||||
|
||||
|
Reference in New Issue
Block a user