/** * This component shows a list of all payment schedules with their associated deadlines (aka. PaymentScheduleItem) and invoices */ import React, { ReactEventHandler, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Loader } from './loader'; import moment from 'moment'; import { IFablab } from '../models/fablab'; import _ from 'lodash'; import { PaymentSchedule, PaymentScheduleItem, PaymentScheduleItemState } from '../models/payment-schedule'; declare var Fablab: IFablab; interface PaymentSchedulesTableProps { paymentSchedules: Array, showCustomer?: boolean } const PaymentSchedulesTableComponent: React.FC = ({ paymentSchedules, showCustomer }) => { const { t } = useTranslation('admin'); const [showExpanded, setShowExpanded] = useState({}); const isExpanded = (paymentScheduleId: number): boolean => { return showExpanded[paymentScheduleId]; } /** * Return the formatted localized date for the given date */ const formatDate = (date: Date): string => { return Intl.DateTimeFormat().format(moment(date).toDate()); } /** * Return the formatted localized amount for the given price (eg. 20.5 => "20,50 €") */ const formatPrice = (price: number): string => { return new Intl.NumberFormat(Fablab.intl_locale, {style: 'currency', currency: Fablab.intl_currency}).format(price); } const statusDisplay = (paymentScheduleId: number): string => { if (isExpanded(paymentScheduleId)) { return 'table-row' } else { return 'none'; } } const expandCollapseIcon = (paymentScheduleId: number): JSX.Element => { if (isExpanded(paymentScheduleId)) { return ; } else { return } } const togglePaymentScheduleDetails = (paymentScheduleId: number): ReactEventHandler => { return (): void => { if (isExpanded(paymentScheduleId)) { setShowExpanded(Object.assign({}, showExpanded, { [paymentScheduleId]: false })); } else { setShowExpanded(Object.assign({}, showExpanded, { [paymentScheduleId]: true })); } } } enum TargetType { Invoice = 'invoices', PaymentSchedule = 'payment_schedules' } const downloadButton = (target: TargetType, id: number): JSX.Element => { const link = `api/${target}/${id}/download`; return ( {t('app.admin.invoices.schedules_table.download')} ); } const formatState = (item: PaymentScheduleItem): JSX.Element => { let res = t(`app.admin.invoices.schedules_table.state_${item.state}`); if (item.state === PaymentScheduleItemState.Paid) { res += ` (${item.payment_method})`; } return {res}; } const itemButtons = (item: PaymentScheduleItem): JSX.Element => { switch (item.state) { case PaymentScheduleItemState.Paid: return downloadButton(TargetType.Invoice, item.invoice_id); case PaymentScheduleItemState.Pending: return (); default: return } } return ( {showCustomer && } {paymentSchedules.map(p => )}
{t('app.admin.invoices.schedules_table.schedule_num')} {t('app.admin.invoices.schedules_table.date')} {t('app.admin.invoices.schedules_table.price')}{t('app.admin.invoices.schedules_table.customer')}
{showCustomer && }
{expandCollapseIcon(p.id)} {p.reference} {formatDate(p.created_at)} {formatPrice(p.total)}{p.user.name}{downloadButton(TargetType.PaymentSchedule, p.id)}
{_.orderBy(p.items, 'due_date').map(item => )}
{t('app.admin.invoices.schedules_table.deadline')} {t('app.admin.invoices.schedules_table.amount')} {t('app.admin.invoices.schedules_table.state')}
{formatDate(item.due_date)} {formatPrice(item.amount)} {formatState(item)} {itemButtons(item)}
); }; PaymentSchedulesTableComponent.defaultProps = { showCustomer: false }; export const PaymentSchedulesTable: React.FC = ({ paymentSchedules, showCustomer }) => { return ( ); }