Skip to content

Commit

Permalink
Show target month of invoice corrections in the UI
Browse files Browse the repository at this point in the history
Creating is deliberately broken, and editing is not possible yet.
  • Loading branch information
akheron committed Oct 3, 2024
1 parent 263cfba commit 8df6ebb
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,22 @@ import FiniteDateRange from 'lib-common/finite-date-range'
import { UpdateStateFn } from 'lib-common/form-state'
import { Action } from 'lib-common/generated/action'
import {
InvoiceCorrection,
InvoiceCorrectionWithPermittedActions,
InvoiceDaycare,
ProductWithName
} from 'lib-common/generated/api-types/invoicing'
import { PersonJSON } from 'lib-common/generated/api-types/pis'
import LocalDate from 'lib-common/local-date'
import { formatCents } from 'lib-common/money'
import { UUID } from 'lib-common/types'
import { useApiState } from 'lib-common/utils/useRestApi'
import AddButton from 'lib-components/atoms/buttons/AddButton'
import { Button } from 'lib-components/atoms/buttons/Button'
import TextArea from 'lib-components/atoms/form/TextArea'
import { InlineAsyncButton } from 'lib-components/employee/notes/InlineAsyncButton'
import { CollapsibleContentArea } from 'lib-components/layout/Container'
import { Table, Tbody, Th, Thead, Tr } from 'lib-components/layout/Table'
import { Table, Tbody, Td, Th, Thead, Tr } from 'lib-components/layout/Table'
import {
FixedSpaceColumn,
FixedSpaceRow
Expand Down Expand Up @@ -288,54 +290,24 @@ const ChildSection = React.memo(function ChildSection({
<Table>
<Thead>
<Tr>
<Th>{i18n.invoiceCorrections.targetMonth}</Th>
<Th>{i18n.invoice.form.rows.product}</Th>
<Th>{i18n.invoice.form.rows.description}</Th>
<Th>{i18n.invoice.form.rows.unitId}</Th>
<Th>{i18n.invoice.form.rows.daterange}</Th>
<Th>{i18n.invoice.form.rows.amount}</Th>
<Th align="right">{i18n.invoice.form.rows.unitPrice}</Th>
<Th align="right">{i18n.invoice.form.rows.price}</Th>
<Th>{i18n.personProfile.invoiceCorrections.invoiceStatusHeader}</Th>
<Th />
</Tr>
</Thead>
<Tbody>
{corrections.map(({ data: correction, permittedActions }) => (
<InvoiceRowSectionRow
{corrections.map(({ data: correction }) => (
<InvoiceCorrectionRow
key={correction.id}
row={{
...correction,
periodStart: correction.period.start,
periodEnd: correction.period.end,
savedCostCenter: null,
price: correction.amount * correction.unitPrice
}}
row={correction}
products={products}
unitIds={unitIds}
unitDetails={unitDetails}
remove={
permittedActions.includes('DELETE') &&
correction.invoiceStatus &&
correction.invoiceStatus !== 'DRAFT'
? undefined
: () => deleteCorrection(correction.id)
}
addNote={() => editNote(correction.id, correction.note)}
status={
correction.invoiceId ? (
<Link to={`/finance/invoices/${correction.invoiceId}`}>
{i18n.personProfile.invoiceCorrections.invoiceStatus(
correction.invoiceStatus
)}
</Link>
) : (
<span>
{i18n.personProfile.invoiceCorrections.invoiceStatus(
correction.invoiceStatus
)}
</span>
)
}
units={unitDetails}
/>
))}
{editState?.childId === child.id && (
Expand All @@ -352,7 +324,7 @@ const ChildSection = React.memo(function ChildSection({
</Tbody>
</Table>
<FlexRow justifyContent="space-between">
{permittedActions.has('CREATE_INVOICE_CORRECTION') && (
{permittedActions.has('CREATE_INVOICE_CORRECTION') ? (
<AddButton
onClick={() => addNewRow(child.id)}
text={i18n.invoiceCorrections.addRow}
Expand Down Expand Up @@ -381,6 +353,37 @@ const ChildSection = React.memo(function ChildSection({
)
})

const InvoiceCorrectionRow = React.memo(function InvoiceCorrectionRow({
row,
units,
products
}: {
row: InvoiceCorrection
units: Record<string, InvoiceDaycare | undefined>
products: ProductWithName[]
}) {
const productName = useMemo(
() => products.find((p) => p.key === row.product)?.nameFi,
[products, row.product]
)

return (
<Tr>
<Td>
{row.targetMonth.month.toString().padStart(2, '0')} /{' '}
{row.targetMonth.year}
</Td>
<Td>{productName}</Td>
<Td>{row.description}</Td>
<Td>{units[row.unitId]?.name ?? ''}</Td>
<Td>{row.period.format()}</Td>
<Td>{row.amount}</Td>
<Td align="right">{formatCents(row.unitPrice)}</Td>
<Td align="right">{formatCents(row.amount * row.unitPrice)}</Td>
</Tr>
)
})

const ChildNameLink = styled(Link)`
width: fit-content;
Expand Down
9 changes: 5 additions & 4 deletions frontend/src/lib-common/generated/api-types/invoicing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import DateRange from '../../date-range'
import FiniteDateRange from '../../finite-date-range'
import HelsinkiDateTime from '../../helsinki-date-time'
import LocalDate from '../../local-date'
import YearMonth from '../../year-month'
import { Action } from '../action'
import { CareType } from './daycare'
import { IncomeAttachment } from './attachment'
Expand Down Expand Up @@ -523,19 +524,18 @@ export interface InvoiceCodes {
}

/**
* Generated from fi.espoo.evaka.invoicing.controller.InvoiceCorrection
* Generated from fi.espoo.evaka.invoicing.service.InvoiceCorrection
*/
export interface InvoiceCorrection {
amount: number
childId: UUID
description: string
headOfFamilyId: UUID
id: UUID
invoiceId: UUID | null
invoiceStatus: InvoiceStatus | null
note: string
period: FiniteDateRange
product: string
targetMonth: YearMonth
unitId: UUID
unitPrice: number
}
Expand Down Expand Up @@ -1305,7 +1305,8 @@ export function deserializeJsonInvoice(json: JsonOf<Invoice>): Invoice {
export function deserializeJsonInvoiceCorrection(json: JsonOf<InvoiceCorrection>): InvoiceCorrection {
return {
...json,
period: FiniteDateRange.parseJson(json.period)
period: FiniteDateRange.parseJson(json.period),
targetMonth: YearMonth.parseIso(json.targetMonth)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2755,6 +2755,7 @@ export const fi = {
},
invoiceCorrections: {
noChildren: 'Henkilö ei ole yhdenkään lapsen päämies',
targetMonth: 'Laskutuskausi',
addRow: 'Lisää korjausrivi'
},
financeDecisions: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ package fi.espoo.evaka.invoicing.controller

import fi.espoo.evaka.Audit
import fi.espoo.evaka.AuditId
import fi.espoo.evaka.invoicing.domain.InvoiceStatus
import fi.espoo.evaka.invoicing.service.InvoiceCorrection
import fi.espoo.evaka.invoicing.service.ProductKey
import fi.espoo.evaka.invoicing.service.getInvoiceCorrectionsForHeadOfFamily
import fi.espoo.evaka.shared.ChildId
import fi.espoo.evaka.shared.DaycareId
import fi.espoo.evaka.shared.InvoiceCorrectionId
import fi.espoo.evaka.shared.InvoiceId
import fi.espoo.evaka.shared.PersonId
import fi.espoo.evaka.shared.auth.AuthenticatedUser
import fi.espoo.evaka.shared.db.Database
Expand Down Expand Up @@ -50,30 +50,7 @@ class InvoiceCorrectionsController(private val accessControl: AccessControl) {
Action.Person.READ_INVOICE_CORRECTIONS,
personId,
)
val invoiceCorrections =
tx.createQuery {
sql(
"""
SELECT c.id, c.head_of_family_id, c.child_id, c.unit_id, c.product, c.period, c.amount, c.unit_price, c.description, c.note,
i.id AS invoice_id,
i.status AS invoice_status
FROM invoice_correction c
LEFT JOIN LATERAL (
SELECT i.id, i.status
FROM invoice_row r
JOIN invoice i ON r.invoice_id = i.id
WHERE c.id = r.correction_id
ORDER BY CASE WHEN i.status = 'DRAFT'::invoice_status THEN 2 ELSE 1 END ASC, i.period_start DESC
LIMIT 1
) i ON true
WHERE
c.head_of_family_id = ${bind(personId)} AND
c.target_month IS NULL AND
NOT applied_completely
"""
)
}
.toList<InvoiceCorrection>()
val invoiceCorrections = tx.getInvoiceCorrectionsForHeadOfFamily(personId)
val permittedActions =
accessControl.getPermittedActions<
InvoiceCorrectionId,
Expand Down Expand Up @@ -217,21 +194,6 @@ RETURNING id
}
}

data class InvoiceCorrection(
val id: InvoiceCorrectionId,
val headOfFamilyId: PersonId,
val childId: ChildId,
val unitId: DaycareId,
val product: ProductKey,
val period: FiniteDateRange,
val amount: Int,
val unitPrice: Int,
val description: String,
val note: String,
val invoiceId: InvoiceId?,
val invoiceStatus: InvoiceStatus?,
)

data class NewInvoiceCorrection(
val headOfFamilyId: PersonId,
val childId: ChildId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import fi.espoo.evaka.shared.db.Predicate
import fi.espoo.evaka.shared.db.PredicateSql
import fi.espoo.evaka.shared.domain.FiniteDateRange
import java.time.YearMonth
import kotlin.math.abs

private fun Database.Read.getInvoiceCorrections(where: Predicate): List<InvoiceCorrection> =
createQuery {
Expand All @@ -31,9 +32,7 @@ SELECT
description,
note
FROM invoice_correction
WHERE
target_month IS NOT NULL AND
${predicate(where.forTable("invoice_correction"))}
WHERE ${predicate(where.forTable("invoice_correction"))}
"""
)
}
Expand All @@ -47,6 +46,15 @@ fun Database.Read.getInvoiceCorrectionsByIds(
): List<InvoiceCorrection> =
getInvoiceCorrections(Predicate { where("$it.id = ANY(${bind(ids)})") })

fun Database.Read.getInvoiceCorrectionsForHeadOfFamily(
personId: PersonId
): List<InvoiceCorrection> =
getInvoiceCorrections(where = Predicate { where("$it.head_of_family_id = ${bind(personId)}") })
.sortedWith(
compareByDescending<InvoiceCorrection> { it.targetMonth }
.thenByDescending { abs(it.amount * it.unitPrice) }
)

fun Database.Transaction.movePastUnappliedInvoiceCorrections(
headOfFamilyIds: Set<PersonId>?,
targetMonth: YearMonth,
Expand Down

0 comments on commit 8df6ebb

Please sign in to comment.