Skip to content

Commit 6346582

Browse files
fix: align inventory unit semantics across purchase and location flows
Normalize stock/price handling to base-checking semantics, fix packaging stock display conversion in purchase suggestions, and show full variant attributes in location product names and UI.
1 parent 52e68f8 commit 6346582

File tree

7 files changed

+611
-136
lines changed

7 files changed

+611
-136
lines changed

backend/src/main/java/com/smalltrend/service/VariantPriceService.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,38 @@ public VariantPriceResponse getActivePrice(Integer variantId) {
101101
*/
102102
@Transactional
103103
public boolean syncActivePurchasePrice(Integer variantId, BigDecimal purchasePrice) {
104-
if (purchasePrice == null) {
104+
if (variantId == null || purchasePrice == null) {
105+
return false;
106+
}
107+
108+
ProductVariant variant = productVariantRepository.findById(variantId).orElse(null);
109+
if (variant == null) {
105110
return false;
106111
}
107112

108113
VariantPrice activePrice = variantPriceRepository
109114
.findFirstByVariantIdAndStatus(variantId, ACTIVE)
110115
.orElse(null);
116+
111117
if (activePrice == null) {
112-
return false;
118+
BigDecimal sellingPrice = variant.getSellPrice() != null ? variant.getSellPrice() : BigDecimal.ZERO;
119+
BigDecimal taxPercent =
120+
variant.getProduct() != null && variant.getProduct().getTaxRate() != null
121+
&& variant.getProduct().getTaxRate().getRate() != null
122+
? variant.getProduct().getTaxRate().getRate()
123+
: BigDecimal.ZERO;
124+
125+
VariantPrice newPrice = VariantPrice.builder()
126+
.variant(variant)
127+
.purchasePrice(purchasePrice)
128+
.sellingPrice(sellingPrice)
129+
.taxPercent(taxPercent)
130+
.effectiveDate(LocalDate.now())
131+
.expiryDate(null)
132+
.status(VariantPriceStatus.ACTIVE)
133+
.build();
134+
variantPriceRepository.save(newPrice);
135+
return true;
113136
}
114137

115138
activePrice.setPurchasePrice(purchasePrice);

backend/src/main/java/com/smalltrend/service/inventory/LocationService.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.smalltrend.dto.inventory.location.LocationStockItemResponse;
66
import com.smalltrend.entity.InventoryStock;
77
import com.smalltrend.entity.Location;
8+
import com.smalltrend.entity.ProductVariant;
89
import com.smalltrend.entity.StockMovement;
910
import com.smalltrend.repository.DisposalVoucherRepository;
1011
import com.smalltrend.repository.InventoryCountRepository;
@@ -20,6 +21,7 @@
2021
import java.time.LocalDateTime;
2122
import java.time.temporal.ChronoUnit;
2223
import java.util.List;
24+
import java.util.Map;
2325
import java.util.Optional;
2426
import java.util.stream.Collectors;
2527

@@ -215,6 +217,34 @@ private String normalizeNullable(String value) {
215217
return trimmed.isEmpty() ? null : trimmed;
216218
}
217219

220+
private String buildDisplayProductName(InventoryStock stock) {
221+
ProductVariant variant = stock.getVariant();
222+
if (variant == null || variant.getProduct() == null) {
223+
return "";
224+
}
225+
226+
String productName = variant.getProduct().getName();
227+
Map<String, String> attributes = variant.getAttributes();
228+
if (attributes == null || attributes.isEmpty()) {
229+
return productName;
230+
}
231+
232+
String attributeText = attributes.entrySet().stream()
233+
.filter(entry -> entry.getValue() != null && !entry.getValue().trim().isEmpty())
234+
.map(entry -> {
235+
String key = entry.getKey() != null ? entry.getKey().trim() : "";
236+
String value = entry.getValue().trim();
237+
return key.isEmpty() ? value : key + " " + value;
238+
})
239+
.collect(Collectors.joining(" - "));
240+
241+
if (attributeText.isBlank()) {
242+
return productName;
243+
}
244+
245+
return productName + " - " + attributeText;
246+
}
247+
218248
private FullLocationResponse toResponseWithStock(Location loc) {
219249
List<InventoryStock> stocks = inventoryStockRepository.findByLocationIdWithProduct(loc.getId());
220250

@@ -260,8 +290,7 @@ private LocationStockItemResponse toStockItemResponse(InventoryStock stock) {
260290
return LocationStockItemResponse.builder()
261291
.variantId(stock.getVariant() != null ? stock.getVariant().getId() : null)
262292
.sku(stock.getVariant() != null ? stock.getVariant().getSku() : "")
263-
.productName(stock.getVariant() != null && stock.getVariant().getProduct() != null
264-
? stock.getVariant().getProduct().getName() : "")
293+
.productName(buildDisplayProductName(stock))
265294
.variantUnit(stock.getVariant() != null && stock.getVariant().getUnit() != null
266295
? stock.getVariant().getUnit().getName() : "")
267296
.quantity(stock.getQuantity() != null ? stock.getQuantity() : 0)

0 commit comments

Comments
 (0)