Skip to content
Open
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9b6319a
LF-5274 Step 17: Add AnimalSaleItem component
kathyavini May 11, 2026
da269b4
LF-5274 Step 21: Add ANIMAL_SALE and ANIMAL_KEY constants
kathyavini May 11, 2026
1e90431
LF-5274 Step 18: Add AnimalSaleInputs container
kathyavini May 11, 2026
c820543
LF-5274 Step 19: Add RevenueSaleInputs dispatcher; rename EntitySaleI…
kathyavini May 11, 2026
9f99348
LF-5274 Step 20: Add animal branches to util.js
kathyavini May 11, 2026
779bc71
LF-5274 Step 22: Wire RevenueDetail to RevenueSaleInputs
kathyavini May 11, 2026
c2cb54a
LF-5274 Step 23: Wire AddSale to RevenueSaleInputs; unblock ANIMAL_SA…
kathyavini May 11, 2026
7469dbb
LF-5274 Step 24: Add animalRevenue transaction type
kathyavini May 11, 2026
154d2ac
LF-5274 Step 31: Add ANIMAL_SALE revenue translation keys
kathyavini May 11, 2026
b235e9d
LF-5274 Register ANIMAL_SALE into iconMap
kathyavini May 11, 2026
781aa96
LF-5274 Update GeneralRevenue and EntitySaleRows according to Figma
kathyavini May 11, 2026
9dea14f
LF-5274 Revert the EntitySaleInputs to EntitySaleRows rename
kathyavini May 12, 2026
cde473a
LF-5274 Rename RevenueSaleInputs
kathyavini May 12, 2026
f0fc254
LF-5274 Rename and reorganization of components
kathyavini May 12, 2026
a88f221
LF-5274 Clean up and update Story
kathyavini May 12, 2026
ca95e6b
LF-5274 Put child components directly into Revenue Form
kathyavini May 13, 2026
843ed58
LF-5274 Expand CropSaleTable into general EntitySaleTable
kathyavini May 13, 2026
b9edf3e
LF-5274 Remove max character part from notes placeholder and match ma…
kathyavini May 13, 2026
180af06
LF-5274 Restore customFormChildren and let containers own ternaries
kathyavini May 13, 2026
f6d423f
LF-5274 Map-based solution to type switching
kathyavini May 13, 2026
a2f8c1a
LF-5274 Fix select placeholders
kathyavini May 13, 2026
fd472c7
LF-5274 Refactor animal and batch formatting functions to use existin…
kathyavini May 13, 2026
241e57c
LF-5274 Refactor getAnimalSaleDefaultValues
kathyavini May 13, 2026
5b67340
LF-5274 Restore EntitySaleInputs wrapper component (sigh)
kathyavini May 13, 2026
b7d99d9
LF-5274 Pass animals and batches to ActualRevenue formatting function
kathyavini May 13, 2026
1c241ae
LF-5274 Update footer of EntitySaleTable as discussed
kathyavini May 13, 2026
1692236
LF-5274 Minor string cleanup
kathyavini May 13, 2026
c9d9701
LF-5274 Clean up RevenueForm stylesheet; lots of unused classes here
kathyavini May 13, 2026
a5ce471
LF-5274 Rename customFormChildrenDefaultValues and fix story
kathyavini May 14, 2026
f826c44
LF-5274 Add missing label to the entity select; match Animal Sale des…
kathyavini May 14, 2026
296565c
LF-5274 Remove unused REVENUE_FORM_TYPE and getRevenueFormType
kathyavini May 14, 2026
b45719e
LF-5274 Rename EntitySaleEntries to EntitySalePicker
kathyavini May 14, 2026
2443b18
LF-5274 Minor cleanup and string fix
kathyavini May 14, 2026
cd6a2dc
LF-5274 Fix circular Redux store import causing Storybook crash
kathyavini May 15, 2026
a5e5df7
LF-5274 Move selectors out of EntitySalePicker component
kathyavini May 15, 2026
073fba6
Merge branch 'integration' into LF-5274-add-animal-batch-selector-wit…
kathyavini May 15, 2026
82e86fb
LF-5274 Minor changes: copyright year formatting and more descriptive…
kathyavini May 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/webapp/public/locales/en/revenue.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"ANIMAL_SALE": {
"REVENUE_NAME": "Animal Sale",
"CUSTOM_DESCRIPTION": "Revenues generated from the sales of animal products."
},
"CROP_SALE": {
"REVENUE_NAME": "Crop Sale",
"CUSTOM_DESCRIPTION": "Revenues associated with the sale of crops harvested from this farm."
Expand Down
5 changes: 5 additions & 0 deletions packages/webapp/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,7 @@
"REVENUE_TYPES": "Search revenue type"
},
"TRANSACTION": {
"ANIMALS": "Animals",
"CROPS": "Crops",
"DAILY_TOTAL": "DAILY TOTAL",
"LABOUR_EXPENSE": "Labour expense",
Expand Down Expand Up @@ -1880,11 +1881,15 @@
"ADD_SALE": {
"ADD_CUSTOM_REVENUE_TYPE": "Add custom revenue type",
"ADD_REVENUE": "Add revenue",
"ANIMAL_NOTES_PLACEHOLDER": "Animal sale description",
"CROP_NOTES_PLACEHOLDER": "Crop sale description",
"CROP_REQUIRED": "Required",
"CROP_VARIETY": "Crop variety",
"FLOW": "revenue creation",
"MANAGE_CUSTOM_REVENUE_TYPE": "Manage custom revenue types",
"NOTES_PLACEHOLDER": "Sale description",
"SALE_VALUE_ERROR": "Sale value must be a positive number less than 999,999,999",
"SELECT_CROPS": "Select crops",
"TABLE_HEADERS": {
"TOTAL": "Total"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import history from '../../../../history';
import styles from './styles.module.scss';
import { createRevenueDetailsUrl } from '../../../../util/siteMapConstants';

const getColumns = (t, mobileView, totalAmount, quantityTotal, currencySymbol) => [
const getColumns = (t, titleLabel, mobileView, totalAmount, currencySymbol) => [
Copy link
Copy Markdown
Collaborator Author

@kathyavini kathyavini May 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to making the table general to both crops and animals by passing the column title, this PR removes the quantity sum and changes "DAILY TOTAL" --> "TOTAL" as discussed in dev-design.

Image

Note: only the mobile view of this table is ever used in app (i.e. the footer is always defined by <FooterCell>, and never by the Footer property of getColumns); therefore the changes to Footer here in getColumns are just for completeness; they don't have any visual effect in app.

{
id: 'title',
label: t('FINANCES.TRANSACTION.CROPS'),
label: t(titleLabel),
format: (d) =>
mobileView ? (
<div className={styles.mobileCrops}>
Expand All @@ -38,7 +38,7 @@ const getColumns = (t, mobileView, totalAmount, quantityTotal, currencySymbol) =
columnProps: {
style: { padding: `0 ${mobileView ? 8 : 12}px` },
},
Footer: mobileView ? null : t('FINANCES.TRANSACTION.DAILY_TOTAL'),
Footer: mobileView ? null : <div className={styles.uppercase}>{t('common:TOTAL')}</div>,
},
{
id: mobileView ? null : 'quantity',
Expand All @@ -48,7 +48,6 @@ const getColumns = (t, mobileView, totalAmount, quantityTotal, currencySymbol) =
columnProps: {
style: { width: '100px' },
},
Footer: mobileView ? null : <div className={styles.bold}>{quantityTotal}</div>,
},
{
id: 'amount',
Expand All @@ -62,20 +61,16 @@ const getColumns = (t, mobileView, totalAmount, quantityTotal, currencySymbol) =
},
];

const FooterCell = ({ t, quantityTotal, totalAmount }) => (
const FooterCell = ({ t, totalAmount }) => (
<div className={styles.mobileCropSaleFooterCell}>
<div>{t('FINANCES.TRANSACTION.DAILY_TOTAL')}</div>
<div className={styles.bold}>{quantityTotal}</div>
<div className={styles.uppercase}>{t('common:TOTAL')}</div>
<div className={styles.bold}>{totalAmount}</div>
</div>
);

export default function CropSaleTable({ data, currencySymbol, mobileView }) {
export default function EntitySaleTable({ data, currencySymbol, mobileView, titleLabel }) {
const { t } = useTranslation();
const { items, amount, relatedId } = data;
const quantityUnit = items?.[0]?.quantityUnit;
const quantityTotal = items.reduce((total, { quantity }) => total + quantity, 0);
const quantityWithUnit = `${quantityTotal} ${quantityUnit}`;
const totalAmount = `${currencySymbol}${amount.toFixed(2)}`;

if (!items?.length) {
Expand All @@ -85,15 +80,11 @@ export default function CropSaleTable({ data, currencySymbol, mobileView }) {
return (
<Table
kind={TableKind.V2}
columns={getColumns(t, mobileView, totalAmount, quantityWithUnit, currencySymbol)}
columns={getColumns(t, titleLabel, mobileView, totalAmount, currencySymbol)}
data={items}
minRows={10}
shouldFixTableLayout={true}
FooterCell={
mobileView
? () => <FooterCell t={t} totalAmount={totalAmount} quantityTotal={quantityWithUnit} />
: null
}
FooterCell={mobileView ? () => <FooterCell t={t} totalAmount={totalAmount} /> : null}
onClickMore={() => history.push(createRevenueDetailsUrl(relatedId))}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,20 @@ import {
LABOUR_URL,
} from '../../../../util/siteMapConstants';
import TextButton from '../../../Form/Button/TextButton';
import CropSaleTable from './CropSaleTable';
import GeneralTransactionTable from './GeneralTransactionTable';
import LabourTable from './LabourTable';
import EntitySaleTable from './EntitySaleTable';
import styles from './styles.module.scss';
import navStyles from '@navStyles';

const components = {
EXPENSE: (props) => <GeneralTransactionTable {...props} />,
REVENUE: (props) => <GeneralTransactionTable {...props} />,
LABOUR_EXPENSE: (props) => <LabourTable {...props} />,
CROP_REVENUE: (props) => <CropSaleTable {...props} />,
CROP_REVENUE: (props) => <EntitySaleTable {...props} titleLabel="FINANCES.TRANSACTION.CROPS" />,
ANIMAL_REVENUE: (props) => (
<EntitySaleTable {...props} titleLabel="FINANCES.TRANSACTION.ANIMALS" />
),
};

const getDetailPageLink = ({ transactionType, relatedId }) => {
Expand All @@ -43,6 +46,7 @@ const getDetailPageLink = ({ transactionType, relatedId }) => {
EXPENSE: createExpenseDetailsUrl(relatedId),
REVENUE: createRevenueDetailsUrl(relatedId),
CROP_REVENUE: createRevenueDetailsUrl(relatedId),
ANIMAL_REVENUE: createRevenueDetailsUrl(relatedId),
}[transactionType];
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ button.toDetail {
font-weight: bold;
}

.uppercase {
text-transform: uppercase;
}

// Crop sales
.mobileCrops {
height: 100%;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2026 LiteFarm.org
* This file is part of LiteFarm.
*
* LiteFarm is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LiteFarm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details, see <https://www.gnu.org/licenses/>.
*/

import { Semibold } from '../../Typography';
import SaleLineItem from './SaleLineItem';
import styles from './styles.module.scss';

interface AnimalSaleItemProps {
animalName: string;
entityId: string;
system: string;
currency: string;
fieldPrefix: string;
entityIdFieldKey: string;
disabledInput: boolean;
}

function AnimalSaleItem({
animalName,
entityId,
system,
currency,
fieldPrefix,
entityIdFieldKey,
disabledInput,
}: AnimalSaleItemProps) {
return (
<div className={styles.saleItemContainer}>
<div className={styles.saleItemInputGroup}>
<Semibold>{animalName}</Semibold>
<SaleLineItem
fieldPrefix={fieldPrefix}
entityId={entityId}
entityIdFieldKey={entityIdFieldKey}
system={system}
currency={currency}
disabledInput={disabledInput}
/>
</div>
</div>
);
}

export default AnimalSaleItem;
Loading