From c396cdcbf9fa2d4a3096b22fdc222585038ec225 Mon Sep 17 00:00:00 2001 From: Thomas Ruoff Date: Wed, 7 Oct 2020 00:32:22 +0200 Subject: [PATCH] further work on billing --- db/bill.ts | 8 ---- db/booking.ts | 12 +++--- db/index.ts | 30 ++++++++++++--- pages/api/booking/[uuid]/bill.ts | 12 +++++- pages/booking/[uuid]/bill.tsx | 64 ++++++++++++++++---------------- pages/booking/[uuid]/index.tsx | 1 + 6 files changed, 75 insertions(+), 52 deletions(-) diff --git a/db/bill.ts b/db/bill.ts index 7ded2fe..b4d8f70 100644 --- a/db/bill.ts +++ b/db/bill.ts @@ -1,6 +1,5 @@ import * as mongoose from 'mongoose' import { BILL_STATUS, MILAGE_RATES, getMilageRateValue } from './enums' -import { BookingDocument } from './booking' export interface AdditionalCosts { name: string @@ -10,7 +9,6 @@ export interface AdditionalCosts { export interface BillDocument extends mongoose.SchemaTimestampsConfig, mongoose.Document { - booking: BookingDocument milageStart: number milageEnd: number milage?: number @@ -23,12 +21,6 @@ export interface BillModel extends mongoose.Model {} const BillSchema = new mongoose.Schema( { - booking: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Booking', - unique: true, - required: true, - }, milageStart: { type: Number, required: true, diff --git a/db/booking.ts b/db/booking.ts index 30b8136..3e2608f 100644 --- a/db/booking.ts +++ b/db/booking.ts @@ -1,6 +1,7 @@ import * as mongoose from 'mongoose' import { v4 as uuidv4 } from 'uuid' import { dateFormatBackend, getDays } from '../helpers/date' +import { BillDocument } from './bill' import { BookerDocument } from './booker' import { BOOKING_STATUS } from './enums' @@ -9,6 +10,7 @@ export interface BookingDocument mongoose.SchemaTimestampsConfig { uuid: string booker: BookerDocument + bill: BillDocument startDate: Date endDate: Date status: BOOKING_STATUS @@ -35,6 +37,11 @@ const BookingSchema = new mongoose.Schema( ref: 'Booker', required: true, }, + bill: { + type: mongoose.Schema.Types.ObjectId, + ref: 'Bill', + required: false, + }, startDate: { type: Date, required: true, @@ -56,11 +63,6 @@ const BookingSchema = new mongoose.Schema( purpose: { type: String, required: false }, org: { type: String, required: false }, destination: { type: String, required: false }, - bill: { - type: mongoose.Schema.Types.ObjectId, - ref: 'bill', - required: false, - }, }, { timestamps: true, diff --git a/db/index.ts b/db/index.ts index f8609d8..4498905 100644 --- a/db/index.ts +++ b/db/index.ts @@ -27,8 +27,8 @@ export async function getBookedDays() { export async function getBookingByUUID(uuid: string) { await connect() - const booking = await Booking.findOne({ uuid }) - return booking?.populate('booker').execPopulate() + return Booking.findOne({ uuid }) + //return booking.populate('bill').populate('booker').execPopulate() } export async function getBookings() { @@ -87,14 +87,32 @@ export async function createBooking({ export async function createBill(bookingUUID: string, billData: BillDocument) { await connect() const booking = await getBookingByUUID(bookingUUID) - const bill = - (await Bill.findOne({ booking: booking._id })) || - new Bill({ booking: booking._id }) + const bill = new Bill() bill.set(billData) await bill.save() - await bill.populate('booking').execPopulate() + + booking.bill = bill._id + await booking.save() + + return bill.toJSON() +} + +export async function patchBill(bookingUUID: string, billData: BillDocument) { + await connect() + const booking = await getBookingByUUID(bookingUUID) + const bill = + (booking.bill && (await Bill.findById(booking.bill))) || + (await Bill.create()) + + bill.set(billData) + await bill.save() + + if (booking.bill !== bill._id) { + booking.bill = bill._id + await booking.save() + } return bill.toJSON() } diff --git a/pages/api/booking/[uuid]/bill.ts b/pages/api/booking/[uuid]/bill.ts index ef6a871..3a151dd 100644 --- a/pages/api/booking/[uuid]/bill.ts +++ b/pages/api/booking/[uuid]/bill.ts @@ -1,6 +1,6 @@ import { NextApiRequest, NextApiResponse } from 'next' import { BillDocument } from '../../../../db/bill' -import { createBill } from '../../../../db/index' +import { createBill, patchBill } from '../../../../db/index' export default async function userHandler( req: NextApiRequest, @@ -26,6 +26,16 @@ export default async function userHandler( return } break + case 'PATCH': + try { + bill = await patchBill(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`) diff --git a/pages/booking/[uuid]/bill.tsx b/pages/booking/[uuid]/bill.tsx index 5afd720..8fdcf93 100644 --- a/pages/booking/[uuid]/bill.tsx +++ b/pages/booking/[uuid]/bill.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react' import Footer from '../../../components/footer' import Header from '../../../components/header' import Input from '../../../components/wizard/input' -import Bill, { AdditionalCosts, BillDocument } from '../../../db/bill' +import { AdditionalCosts, BillDocument } from '../../../db/bill' import { BookingDocument } from '../../../db/booking' import { BILL_STATUS, @@ -20,21 +20,17 @@ export const getServerSideProps: GetServerSideProps = async (context) => { } = context const uuid = Array.isArray(uuids) ? uuids[0] : uuids const booking = await getBookingByUUID(uuid) + await booking.populate('booker').populate('bill').execPopulate() if (!booking) { res.statusCode = 404 res.end() return { props: {} } } - const bill = - (await Bill.findOne({ booking: booking._id })) || - new Bill({ booking: booking._id }) - // TODO: hack, not sure why _id is not serilizable const bookingJSON = JSON.parse(JSON.stringify(booking.toJSON())) - const billJSON = JSON.parse(JSON.stringify(bill?.toJSON())) return { - props: { booking: bookingJSON, bill: billJSON }, + props: { booking: bookingJSON }, } } @@ -82,10 +78,11 @@ async function saveBill( milage?: number rate: MILAGE_RATES additionalCosts?: AdditionalCosts[] + status: BILL_STATUS } -) { +): Promise { const response = await fetch(`/api/booking/${booking.uuid}/bill/`, { - method: 'POST', + method: booking.bill?._id ? 'PATCH' : 'POST', mode: 'cors', cache: 'no-cache', credentials: 'same-origin', @@ -100,17 +97,16 @@ async function saveBill( export default function BillPage({ booking: bookingProp, - bill: billProp, }: { booking: BookingDocument - bill: BillDocument }) { const [booking, setBooking] = useState(bookingProp) - const [bill, setBill] = useState(billProp) - const [milageStart, setMilageStart] = useState(bill.milageStart) - const [milageEnd, setMilageEnd] = useState(bill.milageEnd) - const [rate, setRate] = useState(bill.rate) - const [status, setStatus] = useState(bill.status) + const [milageStart, setMilageStart] = useState(booking.bill?.milageStart) + const [milageEnd, setMilageEnd] = useState(booking.bill?.milageEnd) + const [rate, setRate] = useState( + booking.bill?.rate || MILAGE_RATES.EXTERN_LTE_200 + ) + const [status, setStatus] = useState(booking.bill?.status) const milage = (0 < milageStart && milageStart < milageEnd && milageEnd - milageStart) || 0 const total = @@ -119,25 +115,27 @@ export default function BillPage({ // in case the props change, update the internal state useEffect(() => setBooking(bookingProp), [bookingProp]) - useEffect(() => setBill(billProp), [billProp]) + + const onSubmit = async (event) => { + event.preventDefault() + const bill = await saveBill(booking, { + milageStart, + milageEnd, + milage, + rate, + status, + }) + + booking.bill = bill + setBooking(booking) + } return (

Pfadi Bussle Buchung

-
{ - event.preventDefault() - saveBill(booking, { - milageStart, - milageEnd, - milage, - rate: MILAGE_RATES[rate], - }) - }} - > +
Buchungszeitraum:{' '} {dateFormatFrontend(new Date(booking.startDate))} -{' '} @@ -178,7 +176,9 @@ export default function BillPage({ value={rate} onChange={( e: React.ChangeEvent> - ) => setRate(MILAGE_RATES[e.target.value])} + ) => { + setRate(e.target.value as MILAGE_RATES) + }} > {Object.values(MILAGE_RATES).map((rate) => { return ( @@ -210,7 +210,7 @@ export default function BillPage({ value={status} onChange={( e: React.ChangeEvent> - ) => setStatus(BILL_STATUS[e.target.value])} + ) => setStatus(e.target.value as BILL_STATUS)} > {Object.values(BILL_STATUS).map((status) => { return ( @@ -236,7 +236,7 @@ export default function BillPage({
diff --git a/pages/booking/[uuid]/index.tsx b/pages/booking/[uuid]/index.tsx index d7ba466..1b16831 100644 --- a/pages/booking/[uuid]/index.tsx +++ b/pages/booking/[uuid]/index.tsx @@ -14,6 +14,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { } = context const uuid = Array.isArray(uuids) ? uuids[0] : uuids const booking = await getBookingByUUID(uuid) + await booking.populate('booker').execPopulate() if (!booking) { res.statusCode = 404