diff --git a/packages/api/src/setup.ts b/packages/api/src/setup.ts
index c08090c..aae6945 100644
--- a/packages/api/src/setup.ts
+++ b/packages/api/src/setup.ts
@@ -14,9 +14,11 @@ import {
createInvoiceHandler,
createMolliePaymentHandler,
createBankTransferPaymentHandler,
- createSmartpinPaymentHandler
+ createSmartpinPaymentHandler,
+ createPinPaymentHandler
} from '@modular-api/fastify-checkout'
import { initialize } from './pgboss.js'
+import type { ClientMetadata } from 'oidc-provider'
const getString = (str: string) => str
const host = getString(__HOST__)
@@ -82,6 +84,11 @@ export default async function (fastify: FastifyInstance) {
kysely
})
+ const pinPaymentHandler = createPinPaymentHandler({
+ fastify,
+ kysely
+ })
+
let molliePaymentHandler:
| CheckoutPluginOptionsPaymentHandlers['mollie']
| undefined
@@ -156,11 +163,12 @@ export default async function (fastify: FastifyInstance) {
mollie: molliePaymentHandler,
cash: cashPaymentHandler,
bankTransfer: bankTransferPaymentHandler,
- smartpin: smartpinPaymentHandler
+ smartpin: smartpinPaymentHandler,
+ pin: pinPaymentHandler
}
})
- const clients = [
+ const clients: ClientMetadata[] = [
{
client_id:
env.read('OIDC_CLIENT_ID') ||
diff --git a/packages/app/src/components/invoice/InvoiceExpansionItem.vue b/packages/app/src/components/invoice/InvoiceExpansionItem.vue
index 620f97b..b3c445b 100644
--- a/packages/app/src/components/invoice/InvoiceExpansionItem.vue
+++ b/packages/app/src/components/invoice/InvoiceExpansionItem.vue
@@ -241,7 +241,9 @@
modelValue.status
) &&
modelValue.amountDue &&
- (onAddPaymentCash || onAddPaymentBankTransfer)
+ (onAddPaymentCash ||
+ onAddPaymentBankTransfer ||
+ onAddPaymentPin)
"
clickable
>
@@ -284,6 +286,21 @@
+
+
+
+
+
+
+ {{ lang.payment.methods.pin }}
+
+
+
void
}
): void
+ (
+ e: 'addPaymentPin',
+ {
+ data,
+ done
+ }: {
+ data: Invoice
+ done: (success?: boolean) => void
+ }
+ ): void
(
e: 'sendReceipt',
{
@@ -638,6 +666,12 @@ const addPaymentIdeal = (data: Invoice) => {
}
emit('addPaymentIdeal', { data: data, done })
}
+const addPaymentPin = (data: Invoice) => {
+ function done() {
+ //
+ }
+ emit('addPaymentPin', { data: data, done })
+}
const sendReceipt = (data: Invoice) => {
function done() {
//
diff --git a/packages/app/src/lang/en-US.ts b/packages/app/src/lang/en-US.ts
index 2018df2..5a4e26f 100644
--- a/packages/app/src/lang/en-US.ts
+++ b/packages/app/src/lang/en-US.ts
@@ -218,7 +218,8 @@ const lang: Language = {
methods: {
cash: 'Cash',
bankTransfer: 'Bank transfer',
- ideal: 'iDEAL'
+ ideal: 'iDEAL',
+ pin: 'PIN'
},
messages: {
scanQrOrUseInformationBelow:
diff --git a/packages/app/src/lang/index.ts b/packages/app/src/lang/index.ts
index 9cb370f..92b43f4 100644
--- a/packages/app/src/lang/index.ts
+++ b/packages/app/src/lang/index.ts
@@ -243,6 +243,7 @@ export interface Language {
cash: string
bankTransfer: string
ideal: string
+ pin: string
}
messages: {
scanQrOrUseInformationBelow: string
diff --git a/packages/app/src/lang/nl.ts b/packages/app/src/lang/nl.ts
index 21d3383..a1ceb5e 100644
--- a/packages/app/src/lang/nl.ts
+++ b/packages/app/src/lang/nl.ts
@@ -220,7 +220,8 @@ const lang: Language = {
methods: {
cash: 'Contant',
bankTransfer: 'Bank overschrijving',
- ideal: 'iDEAL'
+ ideal: 'iDEAL',
+ pin: 'PIN'
},
messages: {
scanQrOrUseInformationBelow:
diff --git a/packages/app/src/pages/admin/BillsPage.vue b/packages/app/src/pages/admin/BillsPage.vue
index 8023077..20b2381 100644
--- a/packages/app/src/pages/admin/BillsPage.vue
+++ b/packages/app/src/pages/admin/BillsPage.vue
@@ -41,6 +41,7 @@
@update="openUpdateDialog"
@send-receipt="($event) => openSendBillDialog('receipt')!($event)"
@add-payment-cash="openAddCashPaymentDialog"
+ @add-payment-pin="openAddPinPaymentDialog"
@cancel="openCancelDialog"
/>
@@ -109,7 +110,8 @@ import { InvoiceStatus } from '@slimfact/api/zod'
import { useQuasar, QSelect } from 'quasar'
import CompanySelect from '../../components/company/CompanySelect.vue'
import ClientSelect from '../../components/client/ClientSelect.vue'
-import PriceInputDialog from 'src/components/PriceInputDialog.vue'
+import PriceInputDialog from '../../components/PriceInputDialog.vue'
+import AddPaymentDialog from '../../components/AddPaymentDialog.vue'
const { useQuery, useMutation } = await createUseTrpc()
@@ -290,6 +292,48 @@ const openAddCashPaymentDialog: InstanceType<
})
}
+const openAddPinPaymentDialog: InstanceType<
+ typeof InvoiceExpansionItem
+>['$props']['onMarkPaid'] = async ({ data, done }) => {
+ const format = (value: number) =>
+ Intl.NumberFormat($q.lang.isoName, {
+ maximumFractionDigits: 2,
+ style: 'currency',
+ currency: data.currency
+ }).format(value / 100)
+ return $q
+ .dialog({
+ component: AddPaymentDialog,
+ componentProps: {
+ message: lang.value.invoice.messages.addBankTransferPayment({
+ clientDetails: data.clientDetails,
+ totalIncludingTax: format(data.totalIncludingTax)
+ }),
+ currency: data.currency
+ }
+ })
+ .onOk(async ({ amount, transactionReference }) => {
+ const result = useMutation('admin.addPaymentToInvoice', {
+ args: {
+ id: data.id,
+ payment: {
+ amount,
+ currency: data.currency,
+ description: new Date().toISOString().slice(0, 10),
+ transactionReference,
+ method: PaymentMethod.pin
+ }
+ },
+ immediate: true
+ })
+ await result.immediatePromise
+
+ if (!result.error.value) {
+ await execute()
+ }
+ })
+}
+
const openCancelDialog: InstanceType<
typeof InvoiceExpansionItem
>['$props']['onCancel'] = async ({ data, done }) => {
diff --git a/packages/app/src/pages/admin/InvoicesPage.vue b/packages/app/src/pages/admin/InvoicesPage.vue
index aff00cc..67d61cc 100644
--- a/packages/app/src/pages/admin/InvoicesPage.vue
+++ b/packages/app/src/pages/admin/InvoicesPage.vue
@@ -47,6 +47,7 @@
@cancel="openCancelDialog"
@add-payment-cash="openAddCashPaymentDialog"
@add-payment-bank-transfer="openAddBankTransferPaymentDialog"
+ @add-payment-pin="openAddPinPaymentDialog"
/>
@@ -414,6 +415,48 @@ const openAddBankTransferPaymentDialog: InstanceType<
}
})
}
+
+const openAddPinPaymentDialog: InstanceType<
+ typeof InvoiceExpansionItem
+>['$props']['onMarkPaid'] = async ({ data, done }) => {
+ const format = (value: number) =>
+ Intl.NumberFormat($q.lang.isoName, {
+ maximumFractionDigits: 2,
+ style: 'currency',
+ currency: data.currency
+ }).format(value / 100)
+ return $q
+ .dialog({
+ component: AddPaymentDialog,
+ componentProps: {
+ message: lang.value.invoice.messages.addBankTransferPayment({
+ clientDetails: data.clientDetails,
+ totalIncludingTax: format(data.totalIncludingTax)
+ }),
+ currency: data.currency
+ }
+ })
+ .onOk(async ({ amount, transactionReference }) => {
+ const result = useMutation('admin.addPaymentToInvoice', {
+ args: {
+ id: data.id,
+ payment: {
+ amount,
+ currency: data.currency,
+ description: new Date().toISOString().slice(0, 10),
+ transactionReference,
+ method: PaymentMethod.pin
+ }
+ },
+ immediate: true
+ })
+ await result.immediatePromise
+
+ if (!result.error.value) {
+ await execute()
+ }
+ })
+}
// const openMarkPaidDialog: InstanceType<
// typeof InvoiceExpansionItem
// >['$props']['onMarkPaid'] = async ({ data, done }) => {