enable bill storing

This commit is contained in:
Thomas Ruoff
2020-10-05 00:09:05 +02:00
committed by Thomas Ruoff
parent df6ec51af9
commit ec1b2e9629
7 changed files with 152 additions and 109 deletions

View File

@@ -1,6 +1,7 @@
import * as mongoose from 'mongoose' import * as mongoose from 'mongoose'
import Booker from './booker' import Booker from './booker'
import Booking from './booking' import Booking from './booking'
import Bill, { BillDocument } from './bill'
import { dateFormatFrontend } from '../helpers/date' import { dateFormatFrontend } from '../helpers/date'
import { BOOKING_STATUS } from './enums' import { BOOKING_STATUS } from './enums'
@@ -82,3 +83,15 @@ export async function createBooking({
await booking.populate('booker').execPopulate() await booking.populate('booker').execPopulate()
return booking.toJSON() return booking.toJSON()
} }
export async function createBill(bookingUUID: string, billData: BillDocument) {
await connect()
const bill = new Bill(billData)
const booking = await getBookingByUUID(bookingUUID)
bill.booking = booking._id
await bill.save()
await bill.populate('booking').execPopulate()
return bill.toJSON()
}

View File

@@ -0,0 +1,33 @@
import { NextApiRequest, NextApiResponse } from 'next'
import { BillDocument } from '../../../../db/bill'
import { createBill } from '../../../../db/index'
export default async function userHandler(
req: NextApiRequest,
res: NextApiResponse
) {
const {
method,
query: { uuid: uuids },
} = req
const bookingUUID = Array.isArray(uuids) ? uuids[0] : uuids
let bill: BillDocument
switch (method) {
case 'POST':
try {
bill = await createBill(bookingUUID, req.body)
res.status(200).json(bill)
} catch (e) {
console.error(e)
res.status(500).end(`Internal Server Error...Guru is meditating...`)
return
}
break
default:
res.setHeader('Allow', ['POST'])
res.status(405).end(`Method ${method} Not Allowed`)
}
}

View File

@@ -1,7 +1,7 @@
import { NextApiRequest, NextApiResponse } from 'next' import { NextApiRequest, NextApiResponse } from 'next'
import { BookingDocument } from '../../../db/booking' import { BookingDocument } from '../../../../db/booking'
import { BOOKING_STATUS } from '../../../db/enums' import { BOOKING_STATUS } from '../../../../db/enums'
import { getBookingByUUID } from '../../../db/index' import { getBookingByUUID } from '../../../../db/index'
export default async function userHandler( export default async function userHandler(
req: NextApiRequest, req: NextApiRequest,

View File

@@ -3,6 +3,7 @@ import React, { useEffect, useState } from 'react'
import Footer from '../../../components/footer' import Footer from '../../../components/footer'
import Header from '../../../components/header' import Header from '../../../components/header'
import Input from '../../../components/wizard/input' import Input from '../../../components/wizard/input'
import { BillDocument } from '../../../db/bill'
import { BookingDocument } from '../../../db/booking' import { BookingDocument } from '../../../db/booking'
import { BOOKING_STATUS, MILAGE_RATES } from '../../../db/enums' import { BOOKING_STATUS, MILAGE_RATES } from '../../../db/enums'
import { getBookingByUUID } from '../../../db/index' import { getBookingByUUID } from '../../../db/index'
@@ -44,9 +45,9 @@ function getBookingStatus(booking: BookingDocument) {
} }
} }
async function cancelBooking(booking: BookingDocument) { async function saveBill(booking: BookingDocument, bill: BillDocument) {
const response = await fetch(`/api/booking/${booking.uuid}`, { const response = await fetch(`/api/booking/${booking.uuid}/bill/`, {
method: 'PATCH', method: 'POST',
mode: 'cors', mode: 'cors',
cache: 'no-cache', cache: 'no-cache',
credentials: 'same-origin', credentials: 'same-origin',
@@ -54,7 +55,7 @@ async function cancelBooking(booking: BookingDocument) {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
referrerPolicy: 'no-referrer', referrerPolicy: 'no-referrer',
body: JSON.stringify({ status: BOOKING_STATUS.CANCELED }), body: JSON.stringify(bill),
}) })
return response.json() return response.json()
} }
@@ -69,35 +70,30 @@ export default function Bill({
const [milageEnd, setMilageEnd] = useState(0) const [milageEnd, setMilageEnd] = useState(0)
const [rate, setRate] = useState(MILAGE_RATES.EXTERN_UP_TO_200) const [rate, setRate] = useState(MILAGE_RATES.EXTERN_UP_TO_200)
const milage = const milage =
(0 < milageEnd && (0 < milageStart && milageStart < milageEnd && milageEnd - milageStart) || 0
0 < milageStart && const total = (milage && rate && milage * rate) || 0
milageStart < milageEnd &&
milageEnd - milageStart) ||
0
const total = milage && rate && milage * rate
// in case the props change, update the internal state // in case the props change, update the internal state
useEffect(() => setBooking(bookingProp), [bookingProp]) useEffect(() => setBooking(bookingProp), [bookingProp])
const onCancelBooking = async () => {
if (!confirm('Soll die Buchung wirklich storniert werden?')) {
return
}
try {
const updatedBooking = await cancelBooking(booking)
setBooking(updatedBooking)
} catch (e) {
alert(
'Die Buchung konnte nicht storniert werden. Kontaktieren Sie uns bitt per E-Mail!'
)
}
}
return ( return (
<div className="mx-3 flex flex-col min-h-screen"> <div className="mx-3 flex flex-col min-h-screen">
<Header /> <Header />
<main className="flex-grow"> <main className="flex-grow">
<h2 className="text-3xl">Pfadi Bussle Buchung</h2> <h2 className="text-3xl">Pfadi Bussle Buchung</h2>
<form
className="form"
onSubmit={(event) => {
event.preventDefault()
saveBill(booking, {
milageStart,
milageEnd,
milage,
total,
rate: MILAGE_RATES[rate],
})
}}
>
<div> <div>
<strong>Buchungsstatus:</strong> {getBookingStatus(booking)} <strong>Buchungsstatus:</strong> {getBookingStatus(booking)}
</div> </div>
@@ -182,9 +178,10 @@ export default function Bill({
<Input label="Summe" name="milage" readOnly value={total} /> <Input label="Summe" name="milage" readOnly value={total} />
</div> </div>
<button onClick={onCancelBooking} className="btn btn-blue"> <button type="submit" className="btn btn-blue">
Rechnung Erstellen Rechnung Erstellen
</button> </button>
</form>
</main> </main>
<Footer /> <Footer />