use fixed tarifs and add additional costs

This commit is contained in:
Thomas Ruoff
2020-10-10 00:39:29 +02:00
parent da91a9b09c
commit 396e4b0a86
7 changed files with 185 additions and 89 deletions

View File

@@ -4,20 +4,17 @@ import Footer from '../../../components/footer'
import Header from '../../../components/header'
import Input from '../../../components/input'
import Select from '../../../components/select'
import { AdditionalCosts, BillDocument } from '../../../db/bill'
import { AdditionalCost, BillDocument } from '../../../db/bill'
import { BookingDocument } from '../../../db/booking'
import {
BILL_STATUS,
MILAGE_RATES,
getMilageRateValue,
} from '../../../db/enums'
import { BILL_STATUS, MILAGE_TARIFS } from '../../../db/enums'
import { getBookingByUUID, getMilageMax } from '../../../db/index'
import { dateFormatFrontend } from '../../../helpers/date'
import { getBillTotal } from '../../../helpers/bill'
const milageRateOptions = Object.values(MILAGE_RATES).map((rate) => {
const milageTarifOptions = Object.values(MILAGE_TARIFS).map((tarif) => {
return (
<option value={rate} key={rate}>
{getRateLabel(rate)} ({getMilageRateValue(rate)} EUR)
<option value={tarif} key={tarif}>
{getTarifLabel(tarif)}
</option>
)
})
@@ -54,26 +51,14 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
}
}
function getRateLabel(rate: MILAGE_RATES) {
switch (rate) {
case MILAGE_RATES.INTERN_LTE_200:
return 'Intern bis zu 200km'
case MILAGE_RATES.INTERN_201_1000:
return 'Intern 201-1.000km'
case MILAGE_RATES.INTERN_1001_2000:
return 'Intern 1.001-2.000km'
case MILAGE_RATES.INTERN_GTE_2001:
return 'Intern ab 2.001km'
case MILAGE_RATES.EXTERN_LTE_200:
return 'Extern bis zu 200km'
case MILAGE_RATES.EXTERN_201_1000:
return 'Extern 201-1.000km'
case MILAGE_RATES.EXTERN_1001_2000:
return 'Extern 1.001-2.000km'
case MILAGE_RATES.EXTERN_GTE_2001:
return 'Extern ab 2.001km'
case MILAGE_RATES.FREE_OF_CHARGE:
return 'Frei'
function getTarifLabel(tarif: MILAGE_TARIFS) {
switch (tarif) {
case MILAGE_TARIFS.EXTERN:
return 'Extern'
case MILAGE_TARIFS.INTERN:
return 'Intern'
case MILAGE_TARIFS.NOCHARGE:
return 'Frei von Kosten'
default:
return 'Keine'
}
@@ -98,8 +83,8 @@ async function saveBill(
milageStart: number
milageEnd: number
milage?: number
rate: MILAGE_RATES
additionalCosts?: AdditionalCosts[]
tarif: MILAGE_TARIFS
additionalCosts: AdditionalCost[]
status: BILL_STATUS
}
): Promise<BillDocument> {
@@ -129,17 +114,16 @@ export default function BillPage({
booking.bill?.milageStart || milageMax
)
const [milageEnd, setMilageEnd] = useState(booking.bill?.milageEnd)
const [rate, setRate] = useState(
booking.bill?.rate || MILAGE_RATES.EXTERN_LTE_200
const [tarif, setTarif] = useState(
booking.bill?.tarif || MILAGE_TARIFS.EXTERN
)
const [status, setStatus] = useState(booking.bill?.status)
const [additionalCosts, setAdditionalCosts] = useState([])
const [storingInProgress, setStoringInProgress] = useState(false)
const [storingError, setStoringError] = useState(null)
const milage =
(0 < milageStart && milageStart < milageEnd && milageEnd - milageStart) || 0
const total =
Math.round(milage && rate && milage * getMilageRateValue(rate) * 100) /
100 || 0
const total = getBillTotal({ tarif, milage, additionalCosts })
// in case the props change, update the internal state
useEffect(() => setBooking(bookingProp), [bookingProp])
@@ -154,8 +138,9 @@ export default function BillPage({
milageStart,
milageEnd,
milage,
rate,
tarif,
status,
additionalCosts,
})
booking.bill = bill
@@ -167,11 +152,29 @@ export default function BillPage({
setStoringInProgress(false)
}
const onAddAdditionalCost = function (
event: React.MouseEvent<HTMLButtonElement>
) {
event.preventDefault()
setAdditionalCosts([...additionalCosts, { name: '', value: 0 }])
}
const onRemoveAdditionalCost = function (
event: React.MouseEvent<HTMLButtonElement>,
index: number
) {
event.preventDefault()
setAdditionalCosts([
...additionalCosts.slice(0, index),
...additionalCosts.slice(index + 1),
])
}
return (
<div className="mx-3 flex flex-col min-h-screen">
<Header />
<main className="flex-grow">
<h2 className="text-3xl">Pfadi Bussle Buchung</h2>
<h2 className="text-3xl">Abrechnung</h2>
<form className="form" onSubmit={onSubmit}>
<div>
<strong>Buchungszeitraum:</strong>{' '}
@@ -205,10 +208,10 @@ export default function BillPage({
<Input label="Gefahren" name="milage" readOnly value={milage} />
<Select
label="Rate"
value={rate}
onChange={(e) => setRate(e.target.value as MILAGE_RATES)}
value={tarif}
onChange={(e) => setTarif(e.target.value as MILAGE_TARIFS)}
>
{milageRateOptions}
{milageTarifOptions}
</Select>
<Select
label="Status"
@@ -217,7 +220,66 @@ export default function BillPage({
>
{bookingStatusOptions}
</Select>
<Input label="Summe" name="milage" readOnly value={total} />
<div className="mb-3">
<button
className="ibtn btn-gray mr-3"
onClick={onAddAdditionalCost}
title="Zusätzliche Kosten hinzufügen"
>
+
</button>
<label className="flabel inline">Zusätzliche Kosten</label>
</div>
{additionalCosts.map((_, index) => {
return (
<>
<div className="mb-3" key={`label${index}`}>
<button
className="ibtn btn-gray mr-3"
onClick={(event) => onRemoveAdditionalCost(event, index)}
title="Entfernen"
>
-
</button>
<label className="flabel inline">{`Kostenpunkt ${
index + 1
}`}</label>
</div>
<div className="ml-10 mb-3" key={`input{index}`}>
<Input
label={`Name`}
name={`additionalCostName${index}`}
key={`additionalCostName${index}`}
value={additionalCosts[index].name}
onChange={(event) => {
const newAdditonalCosts = [...additionalCosts]
newAdditonalCosts[index] = {
value: newAdditonalCosts[index].value,
name: event.target.value,
}
setAdditionalCosts(newAdditonalCosts)
}}
/>
<Input
label={`Betrag`}
name={`additionalCostValue${index}`}
key={`additionalCostValue${index}`}
value={additionalCosts[index].value}
type="number"
onChange={(event) => {
const newAdditonalCosts = [...additionalCosts]
newAdditonalCosts[index] = {
name: newAdditonalCosts[index].name,
value: Number(event.target.value),
}
setAdditionalCosts(newAdditonalCosts)
}}
/>
</div>
</>
)
})}
<Input label="Summe" name="total" readOnly value={total} />
</div>
{storingError && (
<div className="error-message flex-grow">{storingError}</div>

View File

@@ -94,7 +94,7 @@ export default function ShowBooking({
<div className="mx-3 flex flex-col min-h-screen">
<Header />
<main className="flex-grow">
<h2 className="text-3xl">Ihre Pfadi Bussle Buchung</h2>
<h2 className="text-3xl">Ihre Buchung</h2>
<div>
<strong>Buchungsstatus:</strong> {getBookingStatus(booking)}
</div>