-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
BOM import: add field selection for item reference (ID/IPN/Name) #10268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8e6553d
f6f07af
ade4f20
48411ed
51e5daf
e7d9867
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2674,6 +2674,11 @@ def is_part_low_on_stock(self): | |
| """Returns True if the total stock for this part is less than the minimum stock level.""" | ||
| return self.get_stock_count() < self.minimum_stock | ||
|
|
||
| @staticmethod | ||
| def import_as_fields(): | ||
| """Return a list of potential ID fields for import.""" | ||
| return ['id', 'IPN', 'name'] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice, this is a simple way to specify the import-as options |
||
|
|
||
|
|
||
| @receiver(post_save, sender=Part, dispatch_uid='part_post_save_log') | ||
| def after_save_part(sender, instance: Part, created, **kwargs): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -126,14 +126,79 @@ function ImporterDefaultField({ | |
| ); | ||
| } | ||
|
|
||
| function ImporterPartImportAsSelect({ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be |
||
| column, | ||
| session | ||
| }: Readonly<{ | ||
| column: any; | ||
| session: ImportSessionState; | ||
| }>) { | ||
| const api = useApi(); | ||
| const [importAsValue, setImportAsValue] = useState<string>(''); | ||
| const importAsKey = `_import_as_${column.field}`; | ||
|
|
||
| useEffect(() => { | ||
| const defaultValue = | ||
| column.import_as && column.import_as.length > 0 | ||
| ? column.import_as[0] | ||
| : ''; | ||
| const value = session.fieldOverrides?.[importAsKey] ?? defaultValue; | ||
| setImportAsValue(value); | ||
| }, [session.fieldOverrides, column.field]); | ||
|
|
||
| const onChange = useCallback( | ||
| (value: any) => { | ||
| const importSettings = { | ||
| ...session.fieldOverrides, | ||
| [importAsKey]: value | ||
| }; | ||
|
|
||
| api | ||
| .patch(apiUrl(ApiEndpoints.import_session_list, session.sessionId), { | ||
| field_overrides: importSettings | ||
| }) | ||
| .then((response) => { | ||
| const value = response.data?.field_overrides?.[importAsKey] ?? ''; | ||
| setImportAsValue(value); | ||
| }) | ||
| .catch((error) => { | ||
| // TODO: Error message? | ||
| }); | ||
| }, | ||
| [column] | ||
| ); | ||
|
|
||
| if (!column.import_as || !Array.isArray(column.import_as)) { | ||
| return null; | ||
| } | ||
|
|
||
| const options = column.import_as.map((option: any) => ({ | ||
| value: option, | ||
| label: option | ||
| })); | ||
|
|
||
| return ( | ||
| <Select | ||
| data={options} | ||
| placeholder={t`Import as`} | ||
| value={importAsValue} | ||
| onChange={onChange} | ||
| size='sm' | ||
| w={180} | ||
| /> | ||
| ); | ||
| } | ||
|
|
||
| function ImporterColumnTableRow({ | ||
| session, | ||
| column, | ||
| options | ||
| options, | ||
| showImportAsColumn | ||
| }: Readonly<{ | ||
| session: ImportSessionState; | ||
| column: any; | ||
| options: any; | ||
| showImportAsColumn: boolean; | ||
| }>) { | ||
| return ( | ||
| <Table.Tr key={column.label ?? column.field}> | ||
|
|
@@ -155,6 +220,11 @@ function ImporterColumnTableRow({ | |
| <Table.Td> | ||
| <ImporterColumn column={column} options={options} /> | ||
| </Table.Td> | ||
| {showImportAsColumn && ( | ||
| <Table.Td> | ||
| <ImporterPartImportAsSelect column={column} session={session} /> | ||
| </Table.Td> | ||
| )} | ||
| <Table.Td> | ||
| <ImporterDefaultField fieldName={column.field} session={session} /> | ||
| </Table.Td> | ||
|
|
@@ -199,6 +269,15 @@ export default function ImporterColumnSelector({ | |
| ]; | ||
| }, [session.availableColumns]); | ||
|
|
||
| const showImportAsColumn = useMemo(() => { | ||
| return session.columnMappings.some( | ||
| (column: any) => | ||
| column.import_as && | ||
| Array.isArray(column.import_as) && | ||
| column.import_as.length > 0 | ||
| ); | ||
| }, [session.columnMappings]); | ||
|
|
||
| return ( | ||
| <Stack gap='xs'> | ||
| <Paper shadow='xs' p='xs'> | ||
|
|
@@ -224,6 +303,7 @@ export default function ImporterColumnSelector({ | |
| <Table.Th>{t`Database Field`}</Table.Th> | ||
| <Table.Th>{t`Field Description`}</Table.Th> | ||
| <Table.Th>{t`Imported Column`}</Table.Th> | ||
| {showImportAsColumn && <Table.Th>{t`Import as`}</Table.Th>} | ||
| <Table.Th>{t`Default Value`}</Table.Th> | ||
| </Table.Tr> | ||
| </Table.Thead> | ||
|
|
@@ -235,6 +315,7 @@ export default function ImporterColumnSelector({ | |
| session={session} | ||
| column={column} | ||
| options={columnOptions} | ||
| showImportAsColumn={showImportAsColumn} | ||
| /> | ||
| ); | ||
| })} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you still have some hard-coded fields here - the "import_as" fields should not have to be called out by name.