2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-17 20:45:44 +00:00

[Pricing] Add option to convert received items currency (#8970)

* Add new global setting

* Convert to base currency on receipt

* Fix total price rendering in PO table

* Fix for tasks.py

* Update .gitignore

- Ignore auto-generated files

* Update docs

Improved documentation for pricing/currency support

* Updates

* Fix caching for default currency

- Now managed better by session caching

* Add unit test for new feature

* Playwright test fixes

* Validate copying of media files

* Validate media files

* Adjust playwright setup

* Allow multiple attempts to fetch release information

* Tweak unit tests

* Revert changes to .gitignore file

- Just trying stuff at this point

* Add debug msg

* Try hard-coded paths

* Remove debug prints

* Abs path for database

* More debug

* Fix typos

* Revert change to db name

* Remove debug statements (again)

* Cleanup playwright tests

* More test tweaks

---------

Co-authored-by: Matthias Mair <code@mjmair.com>
This commit is contained in:
Oliver
2025-02-03 18:34:15 +11:00
committed by GitHub
parent a760d00c96
commit d363c408f8
29 changed files with 250 additions and 134 deletions

View File

@ -252,6 +252,7 @@ export default function SystemSettings() {
keys={[
'PURCHASEORDER_REFERENCE_PATTERN',
'PURCHASEORDER_REQUIRE_RESPONSIBLE',
'PURCHASEORDER_CONVERT_CURRENCY',
'PURCHASEORDER_EDIT_COMPLETED_ORDERS',
'PURCHASEORDER_AUTO_COMPLETE'
]}

View File

@ -32,8 +32,7 @@ import {
NoteColumn,
PartColumn,
ReferenceColumn,
TargetDateColumn,
TotalPriceColumn
TargetDateColumn
} from '../ColumnRenderers';
import type { TableFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable';
@ -226,7 +225,11 @@ export function PurchaseOrderLineItemTable({
accessor: 'purchase_price',
title: t`Unit Price`
}),
TotalPriceColumn(),
CurrencyColumn({
accessor: 'total_price',
currency_accessor: 'purchase_price_currency',
title: t`Total Price`
}),
TargetDateColumn({}),
{
accessor: 'destination',

View File

@ -10,10 +10,11 @@ import { doQuickLogin } from '../login.ts';
test('Build Order - Basic Tests', async ({ page }) => {
await doQuickLogin(page);
await navigate(page, 'part/');
// Navigate to the correct build order
await page.getByRole('tab', { name: 'Manufacturing', exact: true }).click();
await page.getByRole('tab', { name: 'Build Orders', exact: true }).click();
await clearTableFilters(page);
// We have now loaded the "Build Order" table. Check for some expected texts
await page.getByText('On Hold').first().waitFor();
@ -120,6 +121,8 @@ test('Build Order - Build Outputs', async ({ page }) => {
await navigate(page, 'manufacturing/index/');
await page.getByRole('tab', { name: 'Build Orders', exact: true }).click();
await clearTableFilters(page);
// We have now loaded the "Build Order" table. Check for some expected texts
await page.getByText('On Hold').first().waitFor();
await page.getByText('Pending').first().waitFor();

View File

@ -122,6 +122,7 @@ test('Parts - Allocations', async ({ page }) => {
// Navigate to the "Allocations" tab
await page.waitForTimeout(500);
await page.waitForLoadState('networkidle');
await page.getByRole('tab', { name: 'Allocations' }).click();

View File

@ -63,13 +63,9 @@ test('Sales Orders - Tabs', async ({ page }) => {
test('Sales Orders - Basic Tests', async ({ page }) => {
await doQuickLogin(page);
await navigate(page, 'home');
await page.getByRole('tab', { name: 'Sales' }).click();
await page.getByRole('tab', { name: 'Sales Orders' }).click();
// Check for expected text in the table
await page.getByRole('tab', { name: 'Sales Orders' }).waitFor();
await clearTableFilters(page);
await setTableChoiceFilter(page, 'status', 'On Hold');
@ -106,7 +102,6 @@ test('Sales Orders - Basic Tests', async ({ page }) => {
test('Sales Orders - Shipments', async ({ page }) => {
await doQuickLogin(page);
await navigate(page, 'home');
await page.getByRole('tab', { name: 'Sales' }).click();
await page.getByRole('tab', { name: 'Sales Orders' }).click();

View File

@ -60,6 +60,8 @@ test('Report Printing', async ({ page }) => {
// Navigate to a specific PurchaseOrder
await page.getByRole('tab', { name: 'Purchasing' }).click();
await page.getByRole('tab', { name: 'Purchase Orders' }).click();
await page.getByRole('cell', { name: 'PO0009' }).click();
// Select "print report"

View File

@ -95,10 +95,14 @@ test('Settings - Admin', async ({ page }) => {
await page.getByLabel('row-action-menu-0').click();
await page.getByRole('menuitem', { name: 'Edit' }).click();
await expect(page.getByLabel('text-field-name')).toHaveValue('Room');
await expect(page.getByLabel('text-field-description')).toHaveValue('A room');
await page.getByLabel('text-field-name').fill('Large Room');
await page.waitForTimeout(500);
await page.getByLabel('text-field-description').fill('A large room');
// Toggle the "description" field
const oldDescription = await page
.getByLabel('text-field-description')
.inputValue();
const newDescription = `${oldDescription} (edited)`;
await page.getByLabel('text-field-description').fill(newDescription);
await page.waitForTimeout(500);
await page.getByRole('button', { name: 'Submit' }).click();
@ -114,13 +118,9 @@ test('Settings - Admin', async ({ page }) => {
// Edit first item again (revert values)
await page.getByLabel('row-action-menu-0').click();
await page.getByRole('menuitem', { name: 'Edit' }).click();
await expect(page.getByLabel('text-field-name')).toHaveValue('Large Room');
await expect(page.getByLabel('text-field-description')).toHaveValue(
'A large room'
);
await page.getByLabel('text-field-name').fill('Room');
await page.waitForTimeout(500);
await page.getByLabel('text-field-description').fill('A room');
await page.getByLabel('text-field-description').fill(oldDescription);
await page.waitForTimeout(500);
await page.getByRole('button', { name: 'Submit' }).click();
});