Skip to content

Commit

Permalink
Merge branch 'fix/WAL-8062' into 'develop'
Browse files Browse the repository at this point in the history
[WAL-8062] Add selection summary cost to invoice detailed view

See merge request waldur/waldur-homeport!5415
  • Loading branch information
livenson committed Jan 22, 2025
2 parents f8bfb7d + 86928b0 commit 4d0e16f
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 17 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@
"*.fixture.ts",
"*.fixture.tsx",
"src/EventsEnums.ts",
"src/FeaturesEnums.ts",
"src/core/draftjs-module.tsx"
]
},
Expand Down
16 changes: 15 additions & 1 deletion src/invoices/details/BillingRecordDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC } from 'react';
import { FC, useState } from 'react';

import { defaultCurrency } from '@waldur/core/formatCurrency';
import { translate } from '@waldur/i18n';
Expand All @@ -16,16 +16,30 @@ export const BillingRecordDetails: FC<BillingRecordDetailsProps> = ({
invoice,
refreshInvoiceItems,
}) => {
const [totalFiltered, setTotalFiltered] = useState<number | null>(null);

return (
<InvoiceItemsTable
invoice={invoice}
refreshInvoiceItems={refreshInvoiceItems}
showPrice={true}
showVat={false}
setTotalFiltered={setTotalFiltered}
footer={
<table className="table bg-gray-50 border-top border-bottom align-middle">
<tbody>
<tr className="fs-6 fw-bold">
{totalFiltered !== null && (
<td className="text-dark">
<span>{translate('Total filtered')}</span>{' '}
<small>{translate('(VAT is not included)')}</small>
{': '}
<span className="text-end text-dark text-nowrap min-w-125px">
{defaultCurrency(totalFiltered)}
</span>
</td>
)}

<td className="text-end text-dark">
<span>{translate('Total')}</span>{' '}
<small>{translate('(VAT is not included)')}</small>:
Expand Down
24 changes: 22 additions & 2 deletions src/invoices/details/InvoiceDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useState } from 'react';
import { Card, Col, Row } from 'react-bootstrap';
import { useSelector } from 'react-redux';

Expand All @@ -24,6 +25,8 @@ export const InvoiceDetails = ({
customer.payment_profiles,
);

const [totalFiltered, setTotalFiltered] = useState<number | null>(null);

return (
<>
<Card className="card-bordered mb-5">
Expand Down Expand Up @@ -62,11 +65,22 @@ export const InvoiceDetails = ({
refreshInvoiceItems={refreshInvoiceItems}
showPrice={showPrice}
showVat={Boolean(invoice.issuer_details.vat_code)}
setTotalFiltered={setTotalFiltered}
footer={
showPrice && (
<table className="table bg-gray-50 border-top border-bottom align-middle">
<tbody>
<tr className="fs-6 fw-bold">
{totalFiltered !== null && (
<td className="text-dark">
<span>{translate('Total filtered')}</span>
{': '}
<span className="text-end text-dark text-nowrap min-w-125px">
{defaultCurrency(totalFiltered)}
</span>
</td>
)}

<td className="text-end text-dark">
<span>{translate('Subtotal')}:</span>
</td>
Expand All @@ -78,7 +92,10 @@ export const InvoiceDetails = ({
</td>
</tr>
<tr className="fs-6 fw-bold">
<td className="text-end text-dark">
<td
className="text-end text-dark"
colSpan={totalFiltered === null ? 1 : 2}
>
<span>{translate('Tax')}:</span>
</td>
<td
Expand All @@ -89,7 +106,10 @@ export const InvoiceDetails = ({
</td>
</tr>
<tr className="fs-6 fw-bold">
<td className="text-end text-dark">
<td
className="text-end text-dark"
colSpan={totalFiltered === null ? 1 : 2}
>
<span>{translate('Total')}:</span>
</td>
<td
Expand Down
52 changes: 41 additions & 11 deletions src/invoices/details/InvoiceItemsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,15 @@ import { groupInvoiceItems } from './utils';

interface InvoiceItemsTableProps {
invoice: Invoice;
/**
* `invoiceView` is for the user invoice view, when `ENV.accountingMode !== 'accounting'`
* @see `src/invoices/details/BillingDetails.tsx`
* */
invoiceView?: boolean;
refreshInvoiceItems(): void;
showPrice?: boolean;
showVat?: boolean;
setTotalFiltered?(value: number): void;
footer?: ReactNode;
}

Expand Down Expand Up @@ -55,6 +60,7 @@ export const InvoiceItemsTable: FC<InvoiceItemsTableProps> = ({
showVat,
footer,
refreshInvoiceItems,
setTotalFiltered,
}) => {
const filter = useFilters();
const customer = useSelector(getCustomer);
Expand All @@ -66,14 +72,25 @@ export const InvoiceItemsTable: FC<InvoiceItemsTableProps> = ({
const providerUuid = request.filter?.provider_uuid;
const projectUuid = request.filter?.project_uuid;

return Promise.resolve({
rows: groupInvoiceItems(invoice.items).filter(
(item) =>
(!query || item.resource_name.includes(query)) &&
(!providerUuid || item.service_provider_uuid === providerUuid) &&
(!projectUuid || item.project_uuid === projectUuid),
),
});
const rows = groupInvoiceItems(invoice.items).filter(
(item) =>
(!query || item.resource_name.includes(query)) &&
(!providerUuid || item.service_provider_uuid === providerUuid) &&
(!projectUuid || item.project_uuid === projectUuid),
);

if (setTotalFiltered) {
if (query || providerUuid || projectUuid) {
const totalFiltered = invoiceView
? rows.reduce((acc, item) => acc + item.total, 0)
: rows.reduce((acc, item) => acc + item.price, 0);
setTotalFiltered(totalFiltered);
} else {
setTotalFiltered(null);
}
}

return Promise.resolve({ rows });
},
queryField: 'query',
filter,
Expand Down Expand Up @@ -115,13 +132,26 @@ export const InvoiceItemsTable: FC<InvoiceItemsTableProps> = ({
{
title: (
<>
{translate('Total')}
{translate('Price')}
<PriceTooltip />
</>
),
render: ({ row }) => <>{defaultCurrency(row.total)}</>,
className: 'w-150px',
render: ({ row }) => <>{defaultCurrency(row.price)}</>,
className: invoiceView ? undefined : 'w-150px',
},
...(invoiceView
? [
{
title: translate('Tax'),
render: ({ row }) => <>{defaultCurrency(row.tax)}</>,
},
{
title: translate('Total'),
render: ({ row }) => <>{defaultCurrency(row.total)}</>,
className: 'w-150px',
},
]
: []),
]}
title={
<div className="text-nowrap">
Expand Down
4 changes: 4 additions & 0 deletions src/invoices/details/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ export const groupInvoiceItems = (items: InvoiceItem[]): InvoiceTableItem[] => {
service_provider_name: item.details.service_provider_name,
service_provider_uuid: item.details.service_provider_uuid,
plan_name: item.details.plan_name,
price: 0,
tax: 0,
total: 0,
items: [] as InvoiceItem[],
};
}

acc[key].price += Number(item.price);
acc[key].tax += Number(item.tax);
acc[key].total += Number(item.total);

acc[key].items.push(item);
Expand Down
4 changes: 3 additions & 1 deletion src/invoices/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ export interface InvoiceTableItem {
service_provider_name: string;
service_provider_uuid: string;
plan_name: string;
total: 0;
price: number;
tax: number;
total: number;
items: InvoiceItem[];
}

Expand Down
16 changes: 14 additions & 2 deletions template.json
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,10 @@
"description": "features/FeaturesDescription.ts",
"message": "Allow marketplace to function as a catalogue only."
},
"Allow marketplace to serve only as aggregator of call info.": {
"description": "features/FeaturesDescription.ts",
"message": "Allow marketplace to serve only as aggregator of call info."
},
"Allow to enable/disable component only": {
"description": "marketplace/offerings/update/components/ComponentBooleanLimitField.tsx",
"message": "Allow to enable/disable component only"
Expand Down Expand Up @@ -5835,6 +5839,10 @@
"description": "resource/summary/ResourceMetadataDialog.tsx",
"message": "Marketplace UUID"
},
"Marketplace landing page title.": {
"description": "SettingsDescription.ts",
"message": "Marketplace landing page title."
},
"Marketplace offering": {
"description": "marketplace/offerings/OfferingViewHero.tsx",
"message": "Marketplace offering"
Expand Down Expand Up @@ -8028,7 +8036,7 @@
"message": "Price per year"
},
"Price": {
"description": "invoices/list/InvoicesList.tsx, marketplace/offerings/PriceList.tsx, marketplace/resources/change-plan/utils.tsx",
"description": "invoices/details/InvoiceItemsTable.tsx, invoices/list/InvoicesList.tsx, marketplace/offerings/PriceList.tsx, marketplace/resources/change-plan/utils.tsx",
"message": "Price"
},
"Pricelist": {
Expand Down Expand Up @@ -11192,7 +11200,7 @@
"message": "Tax percentage"
},
"Tax": {
"description": "customer/details/CustomerBillingPanel.tsx, invoices/details/InvoiceDetails.tsx, invoices/details/InvoiceItemExpandableRow.tsx, invoices/list/InvoicesList.tsx",
"description": "customer/details/CustomerBillingPanel.tsx, invoices/details/InvoiceDetails.tsx, invoices/details/InvoiceItemExpandableRow.tsx, invoices/details/InvoiceItemsTable.tsx, invoices/list/InvoicesList.tsx",
"message": "Tax"
},
"Team invitations": {
Expand Down Expand Up @@ -11847,6 +11855,10 @@
"description": "customer/list/TotalCostField.tsx",
"message": "Total cost:"
},
"Total filtered": {
"description": "invoices/details/BillingRecordDetails.tsx, invoices/details/InvoiceDetails.tsx",
"message": "Total filtered"
},
"Total for the year": {
"description": "customer/credits/CreditFormDialog.tsx",
"message": "Total for the year"
Expand Down

0 comments on commit 4d0e16f

Please sign in to comment.