mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +00:00 
			
		
		
		
	Delete locations fix (#10672)
* Cleaner handling of inputs * Fix for frontend form: - Fix typo in field - Better option defaults * Tweak part category delete form * Add frontend tests
This commit is contained in:
		| @@ -283,13 +283,11 @@ class CategoryDetail(CategoryMixin, OutputOptionsMixin, CustomRetrieveUpdateDest | ||||
|  | ||||
|     def destroy(self, request, *args, **kwargs): | ||||
|         """Delete a Part category instance via the API.""" | ||||
|         delete_parts = ( | ||||
|             'delete_parts' in request.data and request.data['delete_parts'] == '1' | ||||
|         ) | ||||
|         delete_child_categories = ( | ||||
|             'delete_child_categories' in request.data | ||||
|             and request.data['delete_child_categories'] == '1' | ||||
|         delete_parts = str2bool(request.data.get('delete_parts', False)) | ||||
|         delete_child_categories = str2bool( | ||||
|             request.data.get('delete_child_categories', False) | ||||
|         ) | ||||
|  | ||||
|         return super().destroy( | ||||
|             request, | ||||
|             *args, | ||||
|   | ||||
| @@ -431,8 +431,12 @@ class StockLocationDetail( | ||||
|  | ||||
|     def destroy(self, request, *args, **kwargs): | ||||
|         """Delete a Stock location instance via the API.""" | ||||
|         delete_stock_items = str(request.data.get('delete_stock_items', 0)) == '1' | ||||
|         delete_sub_locations = str(request.data.get('delete_sub_locations', 0)) == '1' | ||||
|         delete_stock_items = InvenTree.helpers.str2bool( | ||||
|             request.data.get('delete_stock_items', False) | ||||
|         ) | ||||
|         delete_sub_locations = InvenTree.helpers.str2bool( | ||||
|             request.data.get('delete_sub_locations', False) | ||||
|         ) | ||||
|  | ||||
|         return super().destroy( | ||||
|             request, | ||||
|   | ||||
| @@ -185,11 +185,11 @@ export default function CategoryDetail() { | ||||
|   const deleteOptions = useMemo(() => { | ||||
|     return [ | ||||
|       { | ||||
|         value: 0, | ||||
|         value: 'false', | ||||
|         display_name: t`Move items to parent category` | ||||
|       }, | ||||
|       { | ||||
|         value: 1, | ||||
|         value: 'true', | ||||
|         display_name: t`Delete items` | ||||
|       } | ||||
|     ]; | ||||
| @@ -204,12 +204,14 @@ export default function CategoryDetail() { | ||||
|         label: t`Parts Action`, | ||||
|         description: t`Action for parts in this category`, | ||||
|         choices: deleteOptions, | ||||
|         required: true, | ||||
|         field_type: 'choice' | ||||
|       }, | ||||
|       delete_child_categories: { | ||||
|         label: t`Child Categories Action`, | ||||
|         description: t`Action for child categories in this category`, | ||||
|         choices: deleteOptions, | ||||
|         required: true, | ||||
|         field_type: 'choice' | ||||
|       } | ||||
|     }, | ||||
|   | ||||
| @@ -218,11 +218,11 @@ export default function Stock() { | ||||
|   const deleteOptions = useMemo(() => { | ||||
|     return [ | ||||
|       { | ||||
|         value: 0, | ||||
|         value: 'false', | ||||
|         display_name: t`Move items to parent location` | ||||
|       }, | ||||
|       { | ||||
|         value: 1, | ||||
|         value: 'true', | ||||
|         display_name: t`Delete items` | ||||
|       } | ||||
|     ]; | ||||
| @@ -235,12 +235,14 @@ export default function Stock() { | ||||
|     fields: { | ||||
|       delete_stock_items: { | ||||
|         label: t`Items Action`, | ||||
|         required: true, | ||||
|         description: t`Action for stock items in this location`, | ||||
|         field_type: 'choice', | ||||
|         choices: deleteOptions | ||||
|       }, | ||||
|       delete_sub_location: { | ||||
|         label: t`Child Locations Action`, | ||||
|       delete_sub_locations: { | ||||
|         label: t`Locations Action`, | ||||
|         required: true, | ||||
|         description: t`Action for child locations in this location`, | ||||
|         field_type: 'choice', | ||||
|         choices: deleteOptions | ||||
|   | ||||
| @@ -54,6 +54,67 @@ test('Stock - Location Tree', async ({ browser }) => { | ||||
|   await page.getByRole('cell', { name: 'Factory' }).first().waitFor(); | ||||
| }); | ||||
|  | ||||
| test('Stock - Location Delete', async ({ browser }) => { | ||||
|   const page = await doCachedLogin(browser, { | ||||
|     url: 'stock/location/38/sublocations' | ||||
|   }); | ||||
|  | ||||
|   // Create a sub-location | ||||
|   await page | ||||
|     .getByRole('button', { name: 'action-button-add-stock-location' }) | ||||
|     .click(); | ||||
|   await page | ||||
|     .getByRole('textbox', { name: 'text-field-name' }) | ||||
|     .fill('my-location-1'); | ||||
|   await page.getByRole('button', { name: 'Submit' }).click(); | ||||
|  | ||||
|   // Create a secondary sub-location | ||||
|   await loadTab(page, 'Sublocations'); | ||||
|   await page | ||||
|     .getByRole('button', { name: 'action-button-add-stock-location' }) | ||||
|     .click(); | ||||
|   await page | ||||
|     .getByRole('textbox', { name: 'text-field-name' }) | ||||
|     .fill('my-location-2'); | ||||
|   await page.getByRole('button', { name: 'Submit' }).click(); | ||||
|  | ||||
|   // Navigate up to parent | ||||
|   await page.getByRole('link', { name: 'breadcrumb-2-my-location-1' }).click(); | ||||
|   await loadTab(page, 'Sublocations'); | ||||
|   await page | ||||
|     .getByRole('cell', { name: 'my-location-2', exact: true }) | ||||
|     .waitFor(); | ||||
|  | ||||
|   // Delete this location, and all child locations | ||||
|   await page | ||||
|     .locator('div') | ||||
|     .filter({ hasText: /^Stock>PCB Assembler>my-location-1Stock Location$/ }) | ||||
|     .getByLabel('action-menu-location-actions') | ||||
|     .click(); | ||||
|   await page | ||||
|     .getByRole('menuitem', { name: 'action-menu-location-actions-delete' }) | ||||
|     .click(); | ||||
|  | ||||
|   await page | ||||
|     .getByRole('textbox', { name: 'choice-field-delete_stock_items' }) | ||||
|     .click(); | ||||
|   await page | ||||
|     .getByRole('option', { name: 'Move items to parent location' }) | ||||
|     .click(); | ||||
|  | ||||
|   await page | ||||
|     .getByRole('textbox', { name: 'choice-field-delete_sub_locations' }) | ||||
|     .click(); | ||||
|   await page.getByRole('option', { name: 'Delete items' }).click(); | ||||
|  | ||||
|   await page.getByRole('button', { name: 'Delete' }).click(); | ||||
|  | ||||
|   // Confirm we are on the right page | ||||
|   await page.getByText('External PCB assembler').waitFor(); | ||||
|   await loadTab(page, 'Sublocations'); | ||||
|   await page.getByText('No records found').first().waitFor(); | ||||
| }); | ||||
|  | ||||
| test('Stock - Filters', async ({ browser }) => { | ||||
|   const page = await doCachedLogin(browser, { | ||||
|     username: 'steven', | ||||
|   | ||||
		Reference in New Issue
	
	Block a user