Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
eda29a3
[add] Add buy reports summary endpoint and related types
nakatashingo Dec 28, 2025
3fa14ff
[add] Implement PurchaseReportSummaryAmounts component and integrate …
nakatashingo Dec 28, 2025
9d47aeb
[otr] Simplify JSX formatting in PurchaseReportSummaryAmounts component
nakatashingo Dec 28, 2025
44167c1
[add] PurchaseReportPaidByFilterModal component and integrate it into…
nakatashingo Dec 31, 2025
3b6ec0a
[fix] Update button text in PurchaseReportPaidByFilterModal
nakatashingo Dec 31, 2025
3c61495
[fix] Update button text in PurchaseReportPaidByFilterModal to improv…
nakatashingo Dec 31, 2025
dff5edd
[add] Implement PurchaseReportSummaryAmounts component and integrate …
nakatashingo Dec 28, 2025
72f01f1
[otr] Simplify JSX formatting in PurchaseReportSummaryAmounts component
nakatashingo Dec 28, 2025
95d6546
[add] PurchaseReportPaidByFilterModal component and integrate it into…
nakatashingo Dec 31, 2025
2c7c7b7
[fix] Update button text in PurchaseReportPaidByFilterModal
nakatashingo Dec 31, 2025
2894b01
[fix] Update button text in PurchaseReportPaidByFilterModal to improv…
nakatashingo Dec 31, 2025
d88ee44
[add] Add "絞り込みなし" option to bureau selection in PurchaseReportPaidBy…
nakatashingo Jan 24, 2026
96fdbdb
refactor: Reorganize imports and clean up whitespace in PurchaseRepor…
nakatashingo Jan 24, 2026
29d8823
formatted by workflow
nakatashingo Jan 24, 2026
ffe2764
[add] Insert additional payment receipt entries in initial schema seed
nakatashingo Jan 30, 2026
1b78882
[fix] Improve styling and structure in PurchaseReportPaidByFilterModa…
nakatashingo Jan 30, 2026
b7cda1c
[fix] Simplify user filtering logic and improve type checking in Purc…
nakatashingo Jan 31, 2026
9dbe13b
[fix] Update PurchaseReportPaidByFilterModal to use paidBy instead of…
nakatashingo Feb 4, 2026
566c3a9
[fix] Enhance PurchaseReportPaidByFilterModal and PurchaseReports to …
nakatashingo Feb 12, 2026
bf65e4f
[add] Implement search functionality and dropdown for paidBy selectio…
nakatashingo May 12, 2026
11ed226
[fix] Refactor filtering logic in PurchaseReports for improved readab…
nakatashingo May 12, 2026
d632646
[add] Create styles for name selection in PurchaseReportPaidByFilterM…
nakatashingo May 12, 2026
a160d56
[fix] Correct CSS background formatting and re-import styles in Purch…
nakatashingo May 12, 2026
38d8d19
[refactor] Remove CSS styles and integrate react-select for name sele…
nakatashingo May 12, 2026
db78d6f
[refactor] Clean up formatting and improve readability in PurchaseRep…
nakatashingo May 12, 2026
0101f1f
Merge branch 'develop' into feat/walt/purchase-report-sort-frontend
nakatashingo May 12, 2026
906cf6a
[refactor] Replace userAtom with useCurrentUser hook in PurchaseRepor…
nakatashingo May 12, 2026
b8d26b8
[fix] Ensure buy report data is updated after status change in Purcha…
nakatashingo May 12, 2026
1c1db0a
[refactor] Improve formatting and readability in PurchaseReportPaidBy…
nakatashingo May 12, 2026
d8d2705
[refactor] Add userNameMap to map user IDs to names in PurchaseReport…
nakatashingo May 12, 2026
090e702
Potential fix for pull request finding
nakatashingo May 18, 2026
423bf00
[refactor] Update menuPortalTarget condition and improve legacyPaidBy…
nakatashingo May 18, 2026
8836ee2
formatted by workflow
nakatashingo May 18, 2026
5dcf621
[refactor] Update currency display logic and encapsulate router push …
nakatashingo May 18, 2026
855e216
[refactor] Simplify users data retrieval and remove redundant isUser …
nakatashingo May 18, 2026
6350641
[fix] Remove incorrect bureau id passed as financial_record_id and fi…
nakatashingo May 18, 2026
da489fe
[fix] Align PurchaseReportPaidByFilterModal prop types with string|nu…
nakatashingo May 18, 2026
6e10e10
[fix] Wire bureau filter to API and scope user fetch to report paid-b…
nakatashingo May 18, 2026
a85e7c5
formatted by workflow
nakatashingo May 18, 2026
4f0bcfc
[revert] Restore seed file to develop state
nakatashingo May 18, 2026
d687193
[fix] Update user fetching condition to ensure valid paidByUserIds
nakatashingo May 18, 2026
7a04dcd
[fix] Refactor class names in PurchaseReportPaidByFilterModal and Pur…
nakatashingo May 18, 2026
a57da05
[feat] Enhance PurchaseReports to include modal user data and legacy …
nakatashingo May 20, 2026
a4d654a
[feat] Enhance buy report filtering to prioritize paid_by_user_id and…
nakatashingo May 28, 2026
6dd6a2f
[feat] Refactor PurchaseReports to streamline filtering and improve b…
nakatashingo May 28, 2026
55274ef
formatted by workflow
nakatashingo May 28, 2026
da79a9d
[feat] Update PurchaseReports to improve state management and optimiz…
nakatashingo May 28, 2026
95d63df
[feat] Add bureau user filtering to displayed buy reports
nakatashingo May 28, 2026
4891a9b
formatted by workflow
nakatashingo May 28, 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
12 changes: 10 additions & 2 deletions api/externals/repository/buy_report_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,17 @@ func applyBuyReportFilters(ds *goqu.SelectDataset, year, financialRecordID, paid
conditions["financial_records.id"] = financialRecordID
}

// paid_by_user_idを優先
if paidByUserID != "" {
conditions["buy_reports.paid_by_user_id"] = paidByUserID
ds = ds.Where(
goqu.Or(
goqu.I("buy_reports.paid_by_user_id").Eq(paidByUserID),
goqu.I("buy_reports.paid_by").Eq(
dialect.From("users").
Select(goqu.I("users.name")).
Where(goqu.I("users.id").Eq(paidByUserID)),
),
),
)
} else if paidBy != "" {
// フォールバック: 文字列で絞り込み
conditions["buy_reports.paid_by"] = paidBy
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import React, { FC, useMemo, useState } from 'react';
import Select, { SingleValue } from 'react-select';

import { normalizePaidBy } from '@/utils/purchaseReportFilters';
import {
CloseButton,
Modal,
OutlinePrimaryButton,
Select as CommonSelect,
} from '@components/common';
import { Bureau, User } from '@type/common';

type NameOption = { value: string; label: string };

interface PurchaseReportPaidByFilterModalProps {
onClose: () => void;
onApply: (selection: {
bureauId: number | null;
paidByUserId: number | null;
paidBy: string | null;
}) => void;
bureaus: Bureau[];
users: User[];
legacyPaidByOptions: string[];
selectedBureauId: number | null;
selectedPaidByUserId: number | null;
selectedPaidBy: string | null;
}

const PurchaseReportPaidByFilterModal: FC<PurchaseReportPaidByFilterModalProps> = (props) => {
const {
onClose,
onApply,
bureaus,
users,
legacyPaidByOptions,
selectedBureauId,
selectedPaidByUserId,
selectedPaidBy,
} = props;

const [draftBureauId, setDraftBureauId] = useState<number | null>(selectedBureauId);
const [draftPaidByUserId, setDraftPaidByUserId] = useState<number | null>(
selectedPaidByUserId ?? null,
);
const [draftPaidBy, setDraftPaidBy] = useState<string | null>(normalizePaidBy(selectedPaidBy));

const labelClassName = 'mb-2 text-sm text-black-600';
const selectTextClassName = 'text-black-600';
const optionClassName = 'text-black-600';

const bureauNameMap = useMemo(
() =>
new Map(
bureaus.map((bureau) => [bureau.id ?? 0, bureau.name] as const).filter(([id]) => id > 0),
),
[bureaus],
);

const filteredUsers = useMemo(() => {
if (!draftBureauId) return users;
return users.filter((user) => user.bureauID === draftBureauId);
}, [draftBureauId, users]);

const nameOptions = useMemo(
(): NameOption[] => [
{ value: '', label: '絞り込みなし' },
...legacyPaidByOptions.map((name) => ({ value: `legacy:${name}`, label: name })),
...filteredUsers.map((u) => {
const bureauName = bureauNameMap.get(u.bureauID);
const label = draftBureauId || !bureauName ? u.name : `${bureauName} ${u.name}`;
return { value: `user:${u.id}`, label };
}),
],
[filteredUsers, legacyPaidByOptions, bureauNameMap, draftBureauId],
);

const nameSelectValue =
draftPaidByUserId != null
? (nameOptions.find((o) => o.value === `user:${draftPaidByUserId}`) ?? nameOptions[0])
: draftPaidBy != null
? (nameOptions.find((o) => o.value === `legacy:${draftPaidBy}`) ?? nameOptions[0])
: nameOptions[0];
Comment on lines +65 to +83

const handleBureauChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const value = event.target.value;
const nextBureauId = value === '' ? null : Number(value);
setDraftBureauId(nextBureauId);
setDraftPaidByUserId(null);
setDraftPaidBy(null);
};

const handleNameChange = (option: SingleValue<NameOption>) => {
const val = option?.value ?? '';
if (val === '') {
setDraftPaidByUserId(null);
setDraftPaidBy(null);
} else if (val.startsWith('user:')) {
const id = Number(val.slice(5));
setDraftPaidByUserId(id);
setDraftPaidBy(users.find((u) => u.id === id)?.name ?? null);
} else {
setDraftPaidByUserId(null);
setDraftPaidBy(val.slice(7));
}
};

const handleApply = () => {
onApply({
bureauId: draftBureauId ?? null,
paidByUserId: draftPaidByUserId ?? null,
paidBy: normalizePaidBy(draftPaidBy),
});
};

return (
<Modal className='w-[90vw] max-w-[440px] p-6 shadow-lg' onClick={onClose}>
<div className='flex justify-end'>
<CloseButton onClick={onClose} />
</div>
<div className='mt-2 space-y-5'>
<div>
<p className={labelClassName}>局名</p>
<CommonSelect
className={selectTextClassName}
value={draftBureauId ?? ''}
onChange={handleBureauChange}
>
<option className={optionClassName} value=''>
絞り込みなし
</option>
{bureaus.map((bureau) => (
<option className={optionClassName} key={bureau.id ?? 0} value={bureau.id ?? 0}>
{bureau.name}
</option>
))}
</CommonSelect>
</div>
<div>
<p className={labelClassName}>氏名</p>
<Select<NameOption>
instanceId='paid-by-name-select'
isSearchable
options={nameOptions}
value={nameSelectValue}
onChange={handleNameChange}
noOptionsMessage={() => '該当なし'}
menuPortalTarget={typeof window !== 'undefined' ? document.body : undefined}
styles={{
control: (base, state) => ({
...base,
borderRadius: '9999px',
borderColor: state.isFocused ? '#48b2cf' : '#56DAFF',
outline: state.isFocused ? '1.5px #48b2cf solid' : 'none',
boxShadow: 'none',
paddingTop: '0.25rem',
paddingBottom: '0.25rem',
paddingLeft: '0.75rem',
paddingRight: '0.25rem',
'&:hover': {
borderColor: state.isFocused ? '#48b2cf' : '#56DAFF',
},
}),
indicatorSeparator: () => ({ display: 'none' }),
menuPortal: (base) => ({ ...base, zIndex: 9999 }),
}}
/>
</div>
</div>
<div className='mt-6 flex justify-center'>
<OutlinePrimaryButton onClick={handleApply}>絞り込む</OutlinePrimaryButton>
</div>
</Modal>
);
};

export default PurchaseReportPaidByFilterModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
interface PurchaseReportSummaryAmountsProps {
unsettledAmountText: string;
unpackedAmountText: string;
className?: string;
}

export default function PurchaseReportSummaryAmounts({
unsettledAmountText,
unpackedAmountText,
className = '',
}: PurchaseReportSummaryAmountsProps) {
return (
<div className={className}>
<div className='text-black-600 inline-grid grid-cols-[auto_auto_auto] gap-1 text-sm leading-normal font-medium'>
<span className='whitespace-nowrap'>未精算金額</span>
<span className='whitespace-nowrap'>:</span>
<span className='min-w-[12ch] text-right whitespace-nowrap'>
{unsettledAmountText}
{unsettledAmountText !== '-' && <span className='ml-1'>円</span>}
</span>
Comment thread
nakatashingo marked this conversation as resolved.

<span className='whitespace-nowrap'>未封詰め金額</span>
<span className='whitespace-nowrap'>:</span>
<span className='min-w-[12ch] text-right whitespace-nowrap'>
{unpackedAmountText}
{unpackedAmountText !== '-' && <span className='ml-1'>円</span>}
</span>
Comment thread
nakatashingo marked this conversation as resolved.
</div>
</div>
);
}
1 change: 1 addition & 0 deletions view/next-project/src/components/purchasereports/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ export { default as PurchaseOrderListModal } from './PurchaseOrderListModal';
export { default as PurchaseReportAddModal } from './PurchaseReportAddModal';
export { default as PurchaseReportConfirmModal } from './PurchaseReportConfirmModal';
export { default as PurchaseReportItemNumModal } from './PurchaseReportItemNumModal'; // "PurchaseReport|temNumModal"を修正しました。
export { default as PurchaseReportSummaryAmounts } from './PurchaseReportSummaryAmounts';
export { default as ReceiptModal } from './ReceiptModal';
export { default as CheckSettlementConfirmModal } from './CheckSettlementConfirmModal';
Loading