Merged PR 1916: fix(remission-helpers, remission-list-item): fix predefinedReturnQuantity han...

fix(remission-helpers, remission-list-item): fix predefinedReturnQuantity handling and enhance stock validation

Fix issue where predefinedReturnQuantity value of 0 was being treated differently
from undefined in mandatory remission (Pflichtremission). Now both 0 and undefined
are handled consistently by changing the initial value to undefined and using
truthy check instead of strict undefined comparison.

Additionally enhance hasStockToRemit validation by requiring both availableStock
and stockToRemit to be greater than 0, preventing invalid remission states when
no stock is available.

Changes:
- Change predefinedReturnQuantity initial value from 0 to undefined in getStockToRemit
- Remove nullish coalescing operator that forced 0 default for predefinedReturnQuantity
- Update calculateStockToRemit to use truthy check (!predefinedReturnQuantity)
  instead of strict undefined comparison
- Enhance hasStockToRemit computed property to validate both availableStock > 0
  and stockToRemit > 0
- Add comprehensive test coverage for all hasStockToRemit edge cases including
  negative values and zero combinations

Ref: #5269
This commit is contained in:
Nino Righi
2025-08-13 09:50:18 +00:00
committed by Andreas Schickinger
parent 99e8e7cfe0
commit 2af16d92ea
3 changed files with 87 additions and 12 deletions

View File

@@ -24,11 +24,11 @@ export const getStockToRemit = ({
availableStock: number;
}): number => {
const remainingQuantityInStock = remissionItem?.remainingQuantityInStock;
let predefinedReturnQuantity: number | undefined = 0;
let predefinedReturnQuantity: number | undefined = undefined; // #5269 Fix - predefinedReturnQuantity 0 soll genauso behandelt werden wie undefined bei Pflichtremission
if (remissionListType === RemissionListType.Pflicht) {
predefinedReturnQuantity =
(remissionItem as ReturnItem)?.predefinedReturnQuantity ?? 0;
predefinedReturnQuantity = (remissionItem as ReturnItem)
?.predefinedReturnQuantity;
}
if (remissionListType === RemissionListType.Abteilung) {
@@ -62,7 +62,7 @@ export const calculateStockToRemit = ({
predefinedReturnQuantity?: number;
remainingQuantityInStock?: number;
}): number => {
if (predefinedReturnQuantity === undefined) {
if (!predefinedReturnQuantity) {
const stockToRemit = availableStock - (remainingQuantityInStock ?? 0);
return stockToRemit < 0 ? 0 : stockToRemit;
}

View File

@@ -374,9 +374,13 @@ describe('RemissionListItemComponent', () => {
});
describe('hasStockToRemit', () => {
it('should return true when stockToRemit > 0', () => {
const { getStockToRemit } = require('@isa/remission/data-access');
it('should return true when both availableStock > 0 and stockToRemit > 0', () => {
const {
getStockToRemit,
calculateAvailableStock,
} = require('@isa/remission/data-access');
getStockToRemit.mockReturnValue(5);
calculateAvailableStock.mockReturnValue(10);
fixture.componentRef.setInput('item', createMockReturnItem());
fixture.componentRef.setInput('stock', createMockStockInfo());
@@ -385,9 +389,13 @@ describe('RemissionListItemComponent', () => {
expect(component.hasStockToRemit()).toBe(true);
});
it('should return false when stockToRemit is 0', () => {
const { getStockToRemit } = require('@isa/remission/data-access');
it('should return false when stockToRemit is 0 even if availableStock > 0', () => {
const {
getStockToRemit,
calculateAvailableStock,
} = require('@isa/remission/data-access');
getStockToRemit.mockReturnValue(0);
calculateAvailableStock.mockReturnValue(10);
fixture.componentRef.setInput('item', createMockReturnItem());
fixture.componentRef.setInput('stock', createMockStockInfo());
@@ -396,9 +404,73 @@ describe('RemissionListItemComponent', () => {
expect(component.hasStockToRemit()).toBe(false);
});
it('should return false when stockToRemit is negative', () => {
const { getStockToRemit } = require('@isa/remission/data-access');
it('should return false when stockToRemit is negative even if availableStock > 0', () => {
const {
getStockToRemit,
calculateAvailableStock,
} = require('@isa/remission/data-access');
getStockToRemit.mockReturnValue(-1);
calculateAvailableStock.mockReturnValue(10);
fixture.componentRef.setInput('item', createMockReturnItem());
fixture.componentRef.setInput('stock', createMockStockInfo());
fixture.detectChanges();
expect(component.hasStockToRemit()).toBe(false);
});
it('should return false when availableStock is 0 even if stockToRemit > 0', () => {
const {
getStockToRemit,
calculateAvailableStock,
} = require('@isa/remission/data-access');
getStockToRemit.mockReturnValue(5);
calculateAvailableStock.mockReturnValue(0);
fixture.componentRef.setInput('item', createMockReturnItem());
fixture.componentRef.setInput('stock', createMockStockInfo());
fixture.detectChanges();
expect(component.hasStockToRemit()).toBe(false);
});
it('should return false when availableStock is negative even if stockToRemit > 0', () => {
const {
getStockToRemit,
calculateAvailableStock,
} = require('@isa/remission/data-access');
getStockToRemit.mockReturnValue(5);
calculateAvailableStock.mockReturnValue(-1);
fixture.componentRef.setInput('item', createMockReturnItem());
fixture.componentRef.setInput('stock', createMockStockInfo());
fixture.detectChanges();
expect(component.hasStockToRemit()).toBe(false);
});
it('should return false when both availableStock and stockToRemit are 0', () => {
const {
getStockToRemit,
calculateAvailableStock,
} = require('@isa/remission/data-access');
getStockToRemit.mockReturnValue(0);
calculateAvailableStock.mockReturnValue(0);
fixture.componentRef.setInput('item', createMockReturnItem());
fixture.componentRef.setInput('stock', createMockStockInfo());
fixture.detectChanges();
expect(component.hasStockToRemit()).toBe(false);
});
it('should return false when both availableStock and stockToRemit are negative', () => {
const {
getStockToRemit,
calculateAvailableStock,
} = require('@isa/remission/data-access');
getStockToRemit.mockReturnValue(-1);
calculateAvailableStock.mockReturnValue(-2);
fixture.componentRef.setInput('item', createMockReturnItem());
fixture.componentRef.setInput('stock', createMockStockInfo());

View File

@@ -126,9 +126,12 @@ export class RemissionListItemComponent {
/**
* Computes whether the item has stock to remit.
* Returns true if stockToRemit is greater than 0.
* Returns true if stockToRemit and availableStock are greater than 0.
* #5269 Added availableStock check
*/
hasStockToRemit = computed(() => this.stockToRemit() > 0);
hasStockToRemit = computed(
() => this.availableStock() > 0 && this.stockToRemit() > 0,
);
/**
* Computes the available stock for the item using stock and removedFromStock.