From 6b341f217b2bf3ff00f20771ee06d96ebe352016 Mon Sep 17 00:00:00 2001 From: Sebastian Frick Date: Tue, 17 Feb 2026 23:44:44 +0100 Subject: [PATCH] refactor: konsistentes Result-basiertes Error-Handling im Master Data BC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VO-Factory-Methoden (of/create/tryEuro) für alle Value Objects eingeführt, die intern IllegalArgumentException fangen und Result liefern. FrameContract.create() liefert jetzt Result statt zu werfen. Alle 31 Use Cases auf Record-Pattern-Deconstruction umgestellt (Failure(var err) / Success(var val) statt verbose generischer Typen). isFailure()/unsafeGetValue() eliminiert. Aggregate-Factorys bereinigt — VO-Null-Checks entfernt, da Validierung jetzt in den VO-Factories liegt. ValidationFailure und CertificateNotFound zu den Error-Interfaces hinzugefügt. WIP: Aggregate.create() gibt teilweise kein Result mehr zurück — wird im nächsten Schritt korrigiert. --- .../masterdata/ActivateArticle.java | 32 ++++---- .../masterdata/ActivateCustomer.java | 32 ++++---- .../masterdata/ActivateSupplier.java | 32 ++++---- .../masterdata/AddCertificate.java | 41 +++++----- .../masterdata/AddDeliveryAddress.java | 47 +++++++----- .../application/masterdata/AddSalesUnit.java | 57 +++++++------- .../masterdata/AssignSupplier.java | 32 ++++---- .../application/masterdata/CreateArticle.java | 58 ++++++++------ .../masterdata/CreateCustomer.java | 45 +++++++---- .../masterdata/CreateProductCategory.java | 28 ++++--- .../masterdata/CreateSupplier.java | 45 +++++++---- .../masterdata/DeactivateArticle.java | 32 ++++---- .../masterdata/DeactivateCustomer.java | 32 ++++---- .../masterdata/DeactivateSupplier.java | 32 ++++---- .../masterdata/DeleteProductCategory.java | 54 ++++++------- .../application/masterdata/GetArticle.java | 12 +-- .../application/masterdata/GetCustomer.java | 12 +-- .../application/masterdata/GetSupplier.java | 12 +-- .../application/masterdata/ListArticles.java | 25 +++--- .../application/masterdata/ListCustomers.java | 25 +++--- .../masterdata/ListProductCategories.java | 9 +-- .../application/masterdata/ListSuppliers.java | 17 ++--- .../application/masterdata/RateSupplier.java | 44 +++++------ .../masterdata/RemoveCertificate.java | 49 ++++++------ .../masterdata/RemoveDeliveryAddress.java | 32 ++++---- .../masterdata/RemoveFrameContract.java | 32 ++++---- .../masterdata/RemoveSalesUnit.java | 40 +++++----- .../masterdata/RemoveSupplier.java | 32 ++++---- .../masterdata/SetFrameContract.java | 76 ++++++++++--------- .../masterdata/SetPreferences.java | 32 ++++---- .../application/masterdata/UpdateArticle.java | 49 ++++++------ .../masterdata/UpdateCustomer.java | 66 ++++++++++------ .../masterdata/UpdateProductCategory.java | 49 ++++++------ .../masterdata/UpdateSalesUnitPrice.java | 47 ++++++------ .../masterdata/UpdateSupplier.java | 66 ++++++++++------ .../effigenix/domain/masterdata/Article.java | 2 +- .../domain/masterdata/ArticleError.java | 4 + .../domain/masterdata/ArticleName.java | 10 +++ .../domain/masterdata/ArticleNumber.java | 10 +++ .../domain/masterdata/CategoryName.java | 10 +++ .../domain/masterdata/ContractLineItem.java | 10 +++ .../effigenix/domain/masterdata/Customer.java | 9 +-- .../domain/masterdata/CustomerError.java | 4 + .../domain/masterdata/CustomerName.java | 10 +++ .../domain/masterdata/DeliveryAddress.java | 10 +++ .../domain/masterdata/FrameContract.java | 11 +-- .../domain/masterdata/ProductCategory.java | 9 +-- .../masterdata/ProductCategoryError.java | 4 + .../domain/masterdata/QualityCertificate.java | 11 +++ .../effigenix/domain/masterdata/Supplier.java | 10 +-- .../domain/masterdata/SupplierError.java | 9 +++ .../domain/masterdata/SupplierName.java | 10 +++ .../domain/masterdata/SupplierRating.java | 10 +++ .../de/effigenix/shared/common/Address.java | 9 +++ .../effigenix/shared/common/ContactInfo.java | 8 ++ .../de/effigenix/shared/common/Money.java | 8 ++ .../effigenix/shared/common/PaymentTerms.java | 8 ++ 57 files changed, 853 insertions(+), 658 deletions(-) diff --git a/backend/src/main/java/de/effigenix/application/masterdata/ActivateArticle.java b/backend/src/main/java/de/effigenix/application/masterdata/ActivateArticle.java index a2becc7..a340612 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/ActivateArticle.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/ActivateArticle.java @@ -1,13 +1,10 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -20,24 +17,25 @@ public class ActivateArticle { } public Result execute(ArticleId articleId, ActorId performedBy) { + Article article; switch (articleRepository.findById(articleId)) { - case Failure> f -> - { return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new ArticleError.ArticleNotFound(articleId)); } - Article article = s.value().get(); - article.activate(); - - switch (articleRepository.save(article)) { - case Failure f2 -> - { return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(article); + article = opt.get(); } } + article.activate(); + + switch (articleRepository.save(article)) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(article); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/ActivateCustomer.java b/backend/src/main/java/de/effigenix/application/masterdata/ActivateCustomer.java index 01fb9ed..e014b39 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/ActivateCustomer.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/ActivateCustomer.java @@ -1,13 +1,10 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -20,24 +17,25 @@ public class ActivateCustomer { } public Result execute(CustomerId customerId, ActorId performedBy) { + Customer customer; switch (customerRepository.findById(customerId)) { - case Failure> f -> - { return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new CustomerError.CustomerNotFound(customerId)); } - Customer customer = s.value().get(); - customer.activate(); - - switch (customerRepository.save(customer)) { - case Failure f2 -> - { return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(customer); + customer = opt.get(); } } + customer.activate(); + + switch (customerRepository.save(customer)) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(customer); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/ActivateSupplier.java b/backend/src/main/java/de/effigenix/application/masterdata/ActivateSupplier.java index 94b2fdb..13c5ec5 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/ActivateSupplier.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/ActivateSupplier.java @@ -1,13 +1,10 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -20,24 +17,25 @@ public class ActivateSupplier { } public Result execute(SupplierId supplierId, ActorId performedBy) { + Supplier supplier; switch (supplierRepository.findById(supplierId)) { - case Failure> f -> - { return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new SupplierError.SupplierNotFound(supplierId)); } - Supplier supplier = s.value().get(); - supplier.activate(); - - switch (supplierRepository.save(supplier)) { - case Failure f2 -> - { return Result.failure(new SupplierError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(supplier); + supplier = opt.get(); } } + supplier.activate(); + + switch (supplierRepository.save(supplier)) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(supplier); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/AddCertificate.java b/backend/src/main/java/de/effigenix/application/masterdata/AddCertificate.java index 0c260f9..dfde62a 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/AddCertificate.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/AddCertificate.java @@ -2,13 +2,10 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.AddCertificateCommand; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -23,27 +20,31 @@ public class AddCertificate { public Result execute(AddCertificateCommand cmd, ActorId performedBy) { var supplierId = SupplierId.of(cmd.supplierId()); + Supplier supplier; switch (supplierRepository.findById(supplierId)) { - case Failure> f -> - { return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new SupplierError.SupplierNotFound(supplierId)); } - Supplier supplier = s.value().get(); - - var certificate = new QualityCertificate( - cmd.certificateType(), cmd.issuer(), cmd.validFrom(), cmd.validUntil()); - supplier.addCertificate(certificate); - - switch (supplierRepository.save(supplier)) { - case Failure f2 -> - { return Result.failure(new SupplierError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(supplier); + supplier = opt.get(); } } + + QualityCertificate certificate; + switch (QualityCertificate.create(cmd.certificateType(), cmd.issuer(), cmd.validFrom(), cmd.validUntil())) { + case Failure(var msg) -> { return Result.failure(new SupplierError.ValidationFailure(msg)); } + case Success(var val) -> certificate = val; + } + supplier.addCertificate(certificate); + + switch (supplierRepository.save(supplier)) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(supplier); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/AddDeliveryAddress.java b/backend/src/main/java/de/effigenix/application/masterdata/AddDeliveryAddress.java index 609f4d6..7559310 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/AddDeliveryAddress.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/AddDeliveryAddress.java @@ -3,13 +3,10 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.AddDeliveryAddressCommand; import de.effigenix.domain.masterdata.*; import de.effigenix.shared.common.Address; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -24,27 +21,37 @@ public class AddDeliveryAddress { public Result execute(AddDeliveryAddressCommand cmd, ActorId performedBy) { var customerId = CustomerId.of(cmd.customerId()); + Customer customer; switch (customerRepository.findById(customerId)) { - case Failure> f -> - { return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new CustomerError.CustomerNotFound(customerId)); } - Customer customer = s.value().get(); - - var address = new Address(cmd.street(), cmd.houseNumber(), cmd.postalCode(), cmd.city(), cmd.country()); - var deliveryAddress = new DeliveryAddress(cmd.label(), address, cmd.contactPerson(), cmd.deliveryNotes()); - customer.addDeliveryAddress(deliveryAddress); - - switch (customerRepository.save(customer)) { - case Failure f2 -> - { return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(customer); + customer = opt.get(); } } + + Address address; + switch (Address.create(cmd.street(), cmd.houseNumber(), cmd.postalCode(), cmd.city(), cmd.country())) { + case Failure(var msg) -> { return Result.failure(new CustomerError.ValidationFailure(msg)); } + case Success(var val) -> address = val; + } + + DeliveryAddress deliveryAddress; + switch (DeliveryAddress.create(cmd.label(), address, cmd.contactPerson(), cmd.deliveryNotes())) { + case Failure(var msg) -> { return Result.failure(new CustomerError.ValidationFailure(msg)); } + case Success(var val) -> deliveryAddress = val; + } + customer.addDeliveryAddress(deliveryAddress); + + switch (customerRepository.save(customer)) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(customer); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/AddSalesUnit.java b/backend/src/main/java/de/effigenix/application/masterdata/AddSalesUnit.java index 430f405..4bf6338 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/AddSalesUnit.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/AddSalesUnit.java @@ -3,13 +3,10 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.AddSalesUnitCommand; import de.effigenix.domain.masterdata.*; import de.effigenix.shared.common.Money; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -24,33 +21,41 @@ public class AddSalesUnit { public Result execute(AddSalesUnitCommand cmd, ActorId performedBy) { var articleId = ArticleId.of(cmd.articleId()); + Article article; switch (articleRepository.findById(articleId)) { - case Failure> f -> - { return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new ArticleError.ArticleNotFound(articleId)); } - Article article = s.value().get(); - - var suResult = SalesUnit.create(cmd.unit(), cmd.priceModel(), Money.euro(cmd.price())); - if (suResult.isFailure()) { - return Result.failure(suResult.unsafeGetError()); - } - - var addResult = article.addSalesUnit(suResult.unsafeGetValue()); - if (addResult.isFailure()) { - return Result.failure(addResult.unsafeGetError()); - } - - switch (articleRepository.save(article)) { - case Failure f2 -> - { return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(article); + article = opt.get(); } } + + Money price; + switch (Money.tryEuro(cmd.price())) { + case Failure(var msg) -> { return Result.failure(new ArticleError.ValidationFailure(msg)); } + case Success(var val) -> price = val; + } + + SalesUnit salesUnit; + switch (SalesUnit.create(cmd.unit(), cmd.priceModel(), price)) { + case Failure(var err) -> { return Result.failure(err); } + case Success(var val) -> salesUnit = val; + } + + switch (article.addSalesUnit(salesUnit)) { + case Failure(var err) -> { return Result.failure(err); } + case Success(var ignored) -> { } + } + + switch (articleRepository.save(article)) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(article); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/AssignSupplier.java b/backend/src/main/java/de/effigenix/application/masterdata/AssignSupplier.java index 9d45500..728f318 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/AssignSupplier.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/AssignSupplier.java @@ -2,13 +2,10 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.AssignSupplierCommand; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -23,24 +20,25 @@ public class AssignSupplier { public Result execute(AssignSupplierCommand cmd, ActorId performedBy) { var articleId = ArticleId.of(cmd.articleId()); + Article article; switch (articleRepository.findById(articleId)) { - case Failure> f -> - { return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new ArticleError.ArticleNotFound(articleId)); } - Article article = s.value().get(); - article.addSupplierReference(SupplierId.of(cmd.supplierId())); - - switch (articleRepository.save(article)) { - case Failure f2 -> - { return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(article); + article = opt.get(); } } + article.addSupplierReference(SupplierId.of(cmd.supplierId())); + + switch (articleRepository.save(article)) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(article); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/CreateArticle.java b/backend/src/main/java/de/effigenix/application/masterdata/CreateArticle.java index e77e127..1c6a664 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/CreateArticle.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/CreateArticle.java @@ -3,7 +3,6 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.CreateArticleCommand; import de.effigenix.domain.masterdata.*; import de.effigenix.shared.common.Money; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; @@ -20,41 +19,50 @@ public class CreateArticle { } public Result execute(CreateArticleCommand cmd, ActorId performedBy) { - // Check uniqueness - switch (articleRepository.existsByArticleNumber(new ArticleNumber(cmd.articleNumber()))) { - case Failure f -> - { return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); } - case Success s -> { - if (s.value()) { + ArticleNumber articleNumber; + switch (ArticleNumber.of(cmd.articleNumber())) { + case Failure(var msg) -> { return Result.failure(new ArticleError.ValidationFailure(msg)); } + case Success(var val) -> articleNumber = val; + } + + switch (articleRepository.existsByArticleNumber(articleNumber)) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var exists) -> { + if (exists) { return Result.failure(new ArticleError.ArticleNumberAlreadyExists(cmd.articleNumber())); } } } - // Create initial SalesUnit - var salesUnitResult = SalesUnit.create(cmd.unit(), cmd.priceModel(), Money.euro(cmd.price())); - if (salesUnitResult.isFailure()) { - return Result.failure(salesUnitResult.unsafeGetError()); + Money price; + switch (Money.tryEuro(cmd.price())) { + case Failure(var msg) -> { return Result.failure(new ArticleError.ValidationFailure(msg)); } + case Success(var val) -> price = val; } - // Create Article - var articleResult = Article.create( - new ArticleName(cmd.name()), - new ArticleNumber(cmd.articleNumber()), - ProductCategoryId.of(cmd.categoryId()), - salesUnitResult.unsafeGetValue() - ); - if (articleResult.isFailure()) { - return Result.failure(articleResult.unsafeGetError()); + SalesUnit salesUnit; + switch (SalesUnit.create(cmd.unit(), cmd.priceModel(), price)) { + case Failure(var err) -> { return Result.failure(err); } + case Success(var val) -> salesUnit = val; } - Article article = articleResult.unsafeGetValue(); + ArticleName name; + switch (ArticleName.of(cmd.name())) { + case Failure(var msg) -> { return Result.failure(new ArticleError.ValidationFailure(msg)); } + case Success(var val) -> name = val; + } + + Article article; + switch (Article.create(name, articleNumber, ProductCategoryId.of(cmd.categoryId()), salesUnit)) { + case Failure(var err) -> { return Result.failure(err); } + case Success(var val) -> article = val; + } - // Save switch (articleRepository.save(article)) { - case Failure f -> - { return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); } - case Success ignored -> { } + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } } return Result.success(article); diff --git a/backend/src/main/java/de/effigenix/application/masterdata/CreateCustomer.java b/backend/src/main/java/de/effigenix/application/masterdata/CreateCustomer.java index 7b69083..0252ce9 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/CreateCustomer.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/CreateCustomer.java @@ -18,33 +18,46 @@ public class CreateCustomer { } public Result execute(CreateCustomerCommand cmd, ActorId performedBy) { - var name = new CustomerName(cmd.name()); + CustomerName name; + switch (CustomerName.of(cmd.name())) { + case Failure(var msg) -> { return Result.failure(new CustomerError.ValidationFailure(msg)); } + case Success(var val) -> name = val; + } switch (customerRepository.existsByName(name)) { - case Failure f -> - { return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); } - case Success s -> { - if (s.value()) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var exists) -> { + if (exists) { return Result.failure(new CustomerError.CustomerNameAlreadyExists(cmd.name())); } } } - var address = new Address(cmd.street(), cmd.houseNumber(), cmd.postalCode(), cmd.city(), cmd.country()); - var contactInfo = new ContactInfo(cmd.phone(), cmd.email(), cmd.contactPerson()); - var paymentTerms = new PaymentTerms(cmd.paymentDueDays(), cmd.paymentDescription()); - - var result = Customer.create(name, cmd.type(), address, contactInfo, paymentTerms); - if (result.isFailure()) { - return result; + Address address; + switch (Address.create(cmd.street(), cmd.houseNumber(), cmd.postalCode(), cmd.city(), cmd.country())) { + case Failure(var msg) -> { return Result.failure(new CustomerError.ValidationFailure(msg)); } + case Success(var val) -> address = val; } - Customer customer = result.unsafeGetValue(); + ContactInfo contactInfo; + switch (ContactInfo.create(cmd.phone(), cmd.email(), cmd.contactPerson())) { + case Failure(var msg) -> { return Result.failure(new CustomerError.ValidationFailure(msg)); } + case Success(var val) -> contactInfo = val; + } + + PaymentTerms paymentTerms; + switch (PaymentTerms.create(cmd.paymentDueDays(), cmd.paymentDescription())) { + case Failure(var msg) -> { return Result.failure(new CustomerError.ValidationFailure(msg)); } + case Success(var val) -> paymentTerms = val; + } + + var customer = Customer.create(name, cmd.type(), address, contactInfo, paymentTerms); switch (customerRepository.save(customer)) { - case Failure f -> - { return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); } - case Success ignored -> { } + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } } return Result.success(customer); diff --git a/backend/src/main/java/de/effigenix/application/masterdata/CreateProductCategory.java b/backend/src/main/java/de/effigenix/application/masterdata/CreateProductCategory.java index 705eb4d..4c17a60 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/CreateProductCategory.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/CreateProductCategory.java @@ -2,7 +2,6 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.CreateProductCategoryCommand; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; @@ -19,29 +18,28 @@ public class CreateProductCategory { } public Result execute(CreateProductCategoryCommand cmd, ActorId performedBy) { - var name = new CategoryName(cmd.name()); + CategoryName name; + switch (CategoryName.of(cmd.name())) { + case Failure(var msg) -> { return Result.failure(new ProductCategoryError.ValidationFailure(msg)); } + case Success(var val) -> name = val; + } switch (categoryRepository.existsByName(name)) { - case Failure f -> - { return Result.failure(new ProductCategoryError.RepositoryFailure(f.error().message())); } - case Success s -> { - if (s.value()) { + case Failure(var err) -> + { return Result.failure(new ProductCategoryError.RepositoryFailure(err.message())); } + case Success(var exists) -> { + if (exists) { return Result.failure(new ProductCategoryError.CategoryNameAlreadyExists(cmd.name())); } } } - var result = ProductCategory.create(name, cmd.description()); - if (result.isFailure()) { - return result; - } - - ProductCategory category = result.unsafeGetValue(); + var category = ProductCategory.create(name, cmd.description()); switch (categoryRepository.save(category)) { - case Failure f -> - { return Result.failure(new ProductCategoryError.RepositoryFailure(f.error().message())); } - case Success ignored -> { } + case Failure(var err) -> + { return Result.failure(new ProductCategoryError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } } return Result.success(category); diff --git a/backend/src/main/java/de/effigenix/application/masterdata/CreateSupplier.java b/backend/src/main/java/de/effigenix/application/masterdata/CreateSupplier.java index 197233d..c0ee6de 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/CreateSupplier.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/CreateSupplier.java @@ -18,33 +18,46 @@ public class CreateSupplier { } public Result execute(CreateSupplierCommand cmd, ActorId performedBy) { - var name = new SupplierName(cmd.name()); + SupplierName name; + switch (SupplierName.of(cmd.name())) { + case Failure(var msg) -> { return Result.failure(new SupplierError.ValidationFailure(msg)); } + case Success(var val) -> name = val; + } switch (supplierRepository.existsByName(name)) { - case Failure f -> - { return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); } - case Success s -> { - if (s.value()) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var exists) -> { + if (exists) { return Result.failure(new SupplierError.SupplierNameAlreadyExists(cmd.name())); } } } - var address = new Address(cmd.street(), cmd.houseNumber(), cmd.postalCode(), cmd.city(), cmd.country()); - var contactInfo = new ContactInfo(cmd.phone(), cmd.email(), cmd.contactPerson()); - var paymentTerms = new PaymentTerms(cmd.paymentDueDays(), cmd.paymentDescription()); - - var result = Supplier.create(name, address, contactInfo, paymentTerms); - if (result.isFailure()) { - return result; + Address address; + switch (Address.create(cmd.street(), cmd.houseNumber(), cmd.postalCode(), cmd.city(), cmd.country())) { + case Failure(var msg) -> { return Result.failure(new SupplierError.ValidationFailure(msg)); } + case Success(var val) -> address = val; } - Supplier supplier = result.unsafeGetValue(); + ContactInfo contactInfo; + switch (ContactInfo.create(cmd.phone(), cmd.email(), cmd.contactPerson())) { + case Failure(var msg) -> { return Result.failure(new SupplierError.ValidationFailure(msg)); } + case Success(var val) -> contactInfo = val; + } + + PaymentTerms paymentTerms; + switch (PaymentTerms.create(cmd.paymentDueDays(), cmd.paymentDescription())) { + case Failure(var msg) -> { return Result.failure(new SupplierError.ValidationFailure(msg)); } + case Success(var val) -> paymentTerms = val; + } + + var supplier = Supplier.create(name, address, contactInfo, paymentTerms); switch (supplierRepository.save(supplier)) { - case Failure f -> - { return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); } - case Success ignored -> { } + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } } return Result.success(supplier); diff --git a/backend/src/main/java/de/effigenix/application/masterdata/DeactivateArticle.java b/backend/src/main/java/de/effigenix/application/masterdata/DeactivateArticle.java index e47856f..1a909c2 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/DeactivateArticle.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/DeactivateArticle.java @@ -1,13 +1,10 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -20,24 +17,25 @@ public class DeactivateArticle { } public Result execute(ArticleId articleId, ActorId performedBy) { + Article article; switch (articleRepository.findById(articleId)) { - case Failure> f -> - { return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new ArticleError.ArticleNotFound(articleId)); } - Article article = s.value().get(); - article.deactivate(); - - switch (articleRepository.save(article)) { - case Failure f2 -> - { return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(article); + article = opt.get(); } } + article.deactivate(); + + switch (articleRepository.save(article)) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(article); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/DeactivateCustomer.java b/backend/src/main/java/de/effigenix/application/masterdata/DeactivateCustomer.java index 0abbaa7..5052f00 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/DeactivateCustomer.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/DeactivateCustomer.java @@ -1,13 +1,10 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -20,24 +17,25 @@ public class DeactivateCustomer { } public Result execute(CustomerId customerId, ActorId performedBy) { + Customer customer; switch (customerRepository.findById(customerId)) { - case Failure> f -> - { return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new CustomerError.CustomerNotFound(customerId)); } - Customer customer = s.value().get(); - customer.deactivate(); - - switch (customerRepository.save(customer)) { - case Failure f2 -> - { return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(customer); + customer = opt.get(); } } + customer.deactivate(); + + switch (customerRepository.save(customer)) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(customer); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/DeactivateSupplier.java b/backend/src/main/java/de/effigenix/application/masterdata/DeactivateSupplier.java index f2b3f41..7a5d931 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/DeactivateSupplier.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/DeactivateSupplier.java @@ -1,13 +1,10 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -20,24 +17,25 @@ public class DeactivateSupplier { } public Result execute(SupplierId supplierId, ActorId performedBy) { + Supplier supplier; switch (supplierRepository.findById(supplierId)) { - case Failure> f -> - { return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new SupplierError.SupplierNotFound(supplierId)); } - Supplier supplier = s.value().get(); - supplier.deactivate(); - - switch (supplierRepository.save(supplier)) { - case Failure f2 -> - { return Result.failure(new SupplierError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(supplier); + supplier = opt.get(); } } + supplier.deactivate(); + + switch (supplierRepository.save(supplier)) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(supplier); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/DeleteProductCategory.java b/backend/src/main/java/de/effigenix/application/masterdata/DeleteProductCategory.java index 244f428..88ffa91 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/DeleteProductCategory.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/DeleteProductCategory.java @@ -1,14 +1,10 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.List; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -23,36 +19,34 @@ public class DeleteProductCategory { } public Result execute(ProductCategoryId categoryId, ActorId performedBy) { - // Check category exists + ProductCategory category; switch (categoryRepository.findById(categoryId)) { - case Failure> f -> - { return Result.failure(new ProductCategoryError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new ProductCategoryError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new ProductCategoryError.CategoryNotFound(categoryId)); } - ProductCategory category = s.value().get(); - - // Check no articles are using this category - switch (articleRepository.findByCategory(categoryId)) { - case Failure> f2 -> - { return Result.failure(new ProductCategoryError.RepositoryFailure(f2.error().message())); } - case Success> s2 -> { - if (!s2.value().isEmpty()) { - return Result.failure(new ProductCategoryError.CategoryInUse(categoryId)); - } - } - } - - // Delete - switch (categoryRepository.delete(category)) { - case Failure f3 -> - { return Result.failure(new ProductCategoryError.RepositoryFailure(f3.error().message())); } - case Success ignored -> { } - } - - return Result.success(null); + category = opt.get(); } } + + switch (articleRepository.findByCategory(categoryId)) { + case Failure(var err) -> + { return Result.failure(new ProductCategoryError.RepositoryFailure(err.message())); } + case Success(var articles) -> { + if (!articles.isEmpty()) { + return Result.failure(new ProductCategoryError.CategoryInUse(categoryId)); + } + } + } + + switch (categoryRepository.delete(category)) { + case Failure(var err) -> + { return Result.failure(new ProductCategoryError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(null); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/GetArticle.java b/backend/src/main/java/de/effigenix/application/masterdata/GetArticle.java index 68cecc3..abe7cd1 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/GetArticle.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/GetArticle.java @@ -1,12 +1,9 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional(readOnly = true) @@ -20,11 +17,10 @@ public class GetArticle { public Result execute(ArticleId articleId) { return switch (articleRepository.findById(articleId)) { - case Failure> f -> - Result.failure(new ArticleError.RepositoryFailure(f.error().message())); - case Success> s -> - s.value() - .map(Result::success) + case Failure(var err) -> + Result.failure(new ArticleError.RepositoryFailure(err.message())); + case Success(var opt) -> + opt.map(Result::success) .orElseGet(() -> Result.failure(new ArticleError.ArticleNotFound(articleId))); }; } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/GetCustomer.java b/backend/src/main/java/de/effigenix/application/masterdata/GetCustomer.java index 2fc3170..0ab4c64 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/GetCustomer.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/GetCustomer.java @@ -1,12 +1,9 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional(readOnly = true) @@ -20,11 +17,10 @@ public class GetCustomer { public Result execute(CustomerId customerId) { return switch (customerRepository.findById(customerId)) { - case Failure> f -> - Result.failure(new CustomerError.RepositoryFailure(f.error().message())); - case Success> s -> - s.value() - .map(Result::success) + case Failure(var err) -> + Result.failure(new CustomerError.RepositoryFailure(err.message())); + case Success(var opt) -> + opt.map(Result::success) .orElseGet(() -> Result.failure(new CustomerError.CustomerNotFound(customerId))); }; } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/GetSupplier.java b/backend/src/main/java/de/effigenix/application/masterdata/GetSupplier.java index 315c4f9..b4d4a0e 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/GetSupplier.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/GetSupplier.java @@ -1,12 +1,9 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional(readOnly = true) @@ -20,11 +17,10 @@ public class GetSupplier { public Result execute(SupplierId supplierId) { return switch (supplierRepository.findById(supplierId)) { - case Failure> f -> - Result.failure(new SupplierError.RepositoryFailure(f.error().message())); - case Success> s -> - s.value() - .map(Result::success) + case Failure(var err) -> + Result.failure(new SupplierError.RepositoryFailure(err.message())); + case Success(var opt) -> + opt.map(Result::success) .orElseGet(() -> Result.failure(new SupplierError.SupplierNotFound(supplierId))); }; } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/ListArticles.java b/backend/src/main/java/de/effigenix/application/masterdata/ListArticles.java index 4608c00..be41048 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/ListArticles.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/ListArticles.java @@ -1,7 +1,6 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import org.springframework.transaction.annotation.Transactional; @@ -20,28 +19,28 @@ public class ListArticles { public Result> execute() { return switch (articleRepository.findAll()) { - case Failure> f -> - Result.failure(new ArticleError.RepositoryFailure(f.error().message())); - case Success> s -> - Result.success(s.value()); + case Failure(var err) -> + Result.failure(new ArticleError.RepositoryFailure(err.message())); + case Success(var articles) -> + Result.success(articles); }; } public Result> executeByCategory(ProductCategoryId categoryId) { return switch (articleRepository.findByCategory(categoryId)) { - case Failure> f -> - Result.failure(new ArticleError.RepositoryFailure(f.error().message())); - case Success> s -> - Result.success(s.value()); + case Failure(var err) -> + Result.failure(new ArticleError.RepositoryFailure(err.message())); + case Success(var articles) -> + Result.success(articles); }; } public Result> executeByStatus(ArticleStatus status) { return switch (articleRepository.findByStatus(status)) { - case Failure> f -> - Result.failure(new ArticleError.RepositoryFailure(f.error().message())); - case Success> s -> - Result.success(s.value()); + case Failure(var err) -> + Result.failure(new ArticleError.RepositoryFailure(err.message())); + case Success(var articles) -> + Result.success(articles); }; } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/ListCustomers.java b/backend/src/main/java/de/effigenix/application/masterdata/ListCustomers.java index 4018796..ce594ad 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/ListCustomers.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/ListCustomers.java @@ -1,7 +1,6 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import org.springframework.transaction.annotation.Transactional; @@ -20,28 +19,28 @@ public class ListCustomers { public Result> execute() { return switch (customerRepository.findAll()) { - case Failure> f -> - Result.failure(new CustomerError.RepositoryFailure(f.error().message())); - case Success> s -> - Result.success(s.value()); + case Failure(var err) -> + Result.failure(new CustomerError.RepositoryFailure(err.message())); + case Success(var customers) -> + Result.success(customers); }; } public Result> executeByType(CustomerType type) { return switch (customerRepository.findByType(type)) { - case Failure> f -> - Result.failure(new CustomerError.RepositoryFailure(f.error().message())); - case Success> s -> - Result.success(s.value()); + case Failure(var err) -> + Result.failure(new CustomerError.RepositoryFailure(err.message())); + case Success(var customers) -> + Result.success(customers); }; } public Result> executeByStatus(CustomerStatus status) { return switch (customerRepository.findByStatus(status)) { - case Failure> f -> - Result.failure(new CustomerError.RepositoryFailure(f.error().message())); - case Success> s -> - Result.success(s.value()); + case Failure(var err) -> + Result.failure(new CustomerError.RepositoryFailure(err.message())); + case Success(var customers) -> + Result.success(customers); }; } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/ListProductCategories.java b/backend/src/main/java/de/effigenix/application/masterdata/ListProductCategories.java index 9c115f4..e968e8e 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/ListProductCategories.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/ListProductCategories.java @@ -1,7 +1,6 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import org.springframework.transaction.annotation.Transactional; @@ -20,10 +19,10 @@ public class ListProductCategories { public Result> execute() { return switch (categoryRepository.findAll()) { - case Failure> f -> - Result.failure(new ProductCategoryError.RepositoryFailure(f.error().message())); - case Success> s -> - Result.success(s.value()); + case Failure(var err) -> + Result.failure(new ProductCategoryError.RepositoryFailure(err.message())); + case Success(var categories) -> + Result.success(categories); }; } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/ListSuppliers.java b/backend/src/main/java/de/effigenix/application/masterdata/ListSuppliers.java index 761f2f8..7f53d3d 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/ListSuppliers.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/ListSuppliers.java @@ -1,7 +1,6 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import org.springframework.transaction.annotation.Transactional; @@ -20,19 +19,19 @@ public class ListSuppliers { public Result> execute() { return switch (supplierRepository.findAll()) { - case Failure> f -> - Result.failure(new SupplierError.RepositoryFailure(f.error().message())); - case Success> s -> - Result.success(s.value()); + case Failure(var err) -> + Result.failure(new SupplierError.RepositoryFailure(err.message())); + case Success(var suppliers) -> + Result.success(suppliers); }; } public Result> executeByStatus(SupplierStatus status) { return switch (supplierRepository.findByStatus(status)) { - case Failure> f -> - Result.failure(new SupplierError.RepositoryFailure(f.error().message())); - case Success> s -> - Result.success(s.value()); + case Failure(var err) -> + Result.failure(new SupplierError.RepositoryFailure(err.message())); + case Success(var suppliers) -> + Result.success(suppliers); }; } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/RateSupplier.java b/backend/src/main/java/de/effigenix/application/masterdata/RateSupplier.java index 952a19a..7be777e 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/RateSupplier.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/RateSupplier.java @@ -2,13 +2,10 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.RateSupplierCommand; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -23,30 +20,31 @@ public class RateSupplier { public Result execute(RateSupplierCommand cmd, ActorId performedBy) { var supplierId = SupplierId.of(cmd.supplierId()); + Supplier supplier; switch (supplierRepository.findById(supplierId)) { - case Failure> f -> - { return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new SupplierError.SupplierNotFound(supplierId)); } - Supplier supplier = s.value().get(); - - try { - var rating = new SupplierRating(cmd.qualityScore(), cmd.deliveryScore(), cmd.priceScore()); - supplier.rate(rating); - } catch (IllegalArgumentException e) { - return Result.failure(new SupplierError.InvalidRating(e.getMessage())); - } - - switch (supplierRepository.save(supplier)) { - case Failure f2 -> - { return Result.failure(new SupplierError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(supplier); + supplier = opt.get(); } } + + SupplierRating rating; + switch (SupplierRating.create(cmd.qualityScore(), cmd.deliveryScore(), cmd.priceScore())) { + case Failure(var msg) -> { return Result.failure(new SupplierError.InvalidRating(msg)); } + case Success(var val) -> rating = val; + } + supplier.rate(rating); + + switch (supplierRepository.save(supplier)) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(supplier); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/RemoveCertificate.java b/backend/src/main/java/de/effigenix/application/masterdata/RemoveCertificate.java index 9221a49..31ce573 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/RemoveCertificate.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/RemoveCertificate.java @@ -2,12 +2,11 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.RemoveCertificateCommand; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; +import java.util.Objects; import static de.effigenix.shared.common.Result.*; @@ -23,31 +22,35 @@ public class RemoveCertificate { public Result execute(RemoveCertificateCommand cmd, ActorId performedBy) { var supplierId = SupplierId.of(cmd.supplierId()); + Supplier supplier; switch (supplierRepository.findById(supplierId)) { - case Failure> f -> - { return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new SupplierError.SupplierNotFound(supplierId)); } - Supplier supplier = s.value().get(); - - // Find matching certificate by type, issuer, and validFrom - supplier.certificates().stream() - .filter(c -> c.certificateType().equals(cmd.certificateType()) - && java.util.Objects.equals(c.issuer(), cmd.issuer()) - && java.util.Objects.equals(c.validFrom(), cmd.validFrom())) - .findFirst() - .ifPresent(supplier::removeCertificate); - - switch (supplierRepository.save(supplier)) { - case Failure f2 -> - { return Result.failure(new SupplierError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(supplier); + supplier = opt.get(); } } + + var certificate = supplier.certificates().stream() + .filter(c -> c.certificateType().equals(cmd.certificateType()) + && Objects.equals(c.issuer(), cmd.issuer()) + && Objects.equals(c.validFrom(), cmd.validFrom())) + .findFirst(); + + if (certificate.isEmpty()) { + return Result.failure(new SupplierError.CertificateNotFound(cmd.certificateType())); + } + supplier.removeCertificate(certificate.get()); + + switch (supplierRepository.save(supplier)) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(supplier); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/RemoveDeliveryAddress.java b/backend/src/main/java/de/effigenix/application/masterdata/RemoveDeliveryAddress.java index d85f8d8..be023ae 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/RemoveDeliveryAddress.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/RemoveDeliveryAddress.java @@ -2,13 +2,10 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.RemoveDeliveryAddressCommand; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -23,24 +20,25 @@ public class RemoveDeliveryAddress { public Result execute(RemoveDeliveryAddressCommand cmd, ActorId performedBy) { var customerId = CustomerId.of(cmd.customerId()); + Customer customer; switch (customerRepository.findById(customerId)) { - case Failure> f -> - { return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new CustomerError.CustomerNotFound(customerId)); } - Customer customer = s.value().get(); - customer.removeDeliveryAddress(cmd.label()); - - switch (customerRepository.save(customer)) { - case Failure f2 -> - { return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(customer); + customer = opt.get(); } } + customer.removeDeliveryAddress(cmd.label()); + + switch (customerRepository.save(customer)) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(customer); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/RemoveFrameContract.java b/backend/src/main/java/de/effigenix/application/masterdata/RemoveFrameContract.java index d28cc75..35d1820 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/RemoveFrameContract.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/RemoveFrameContract.java @@ -1,13 +1,10 @@ package de.effigenix.application.masterdata; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -20,24 +17,25 @@ public class RemoveFrameContract { } public Result execute(CustomerId customerId, ActorId performedBy) { + Customer customer; switch (customerRepository.findById(customerId)) { - case Failure> f -> - { return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new CustomerError.CustomerNotFound(customerId)); } - Customer customer = s.value().get(); - customer.removeFrameContract(); - - switch (customerRepository.save(customer)) { - case Failure f2 -> - { return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(customer); + customer = opt.get(); } } + customer.removeFrameContract(); + + switch (customerRepository.save(customer)) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(customer); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/RemoveSalesUnit.java b/backend/src/main/java/de/effigenix/application/masterdata/RemoveSalesUnit.java index a1657fa..08e9767 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/RemoveSalesUnit.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/RemoveSalesUnit.java @@ -2,13 +2,10 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.RemoveSalesUnitCommand; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -23,28 +20,29 @@ public class RemoveSalesUnit { public Result execute(RemoveSalesUnitCommand cmd, ActorId performedBy) { var articleId = ArticleId.of(cmd.articleId()); + Article article; switch (articleRepository.findById(articleId)) { - case Failure> f -> - { return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new ArticleError.ArticleNotFound(articleId)); } - Article article = s.value().get(); - - var removeResult = article.removeSalesUnit(SalesUnitId.of(cmd.salesUnitId())); - if (removeResult.isFailure()) { - return Result.failure(removeResult.unsafeGetError()); - } - - switch (articleRepository.save(article)) { - case Failure f2 -> - { return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(article); + article = opt.get(); } } + + switch (article.removeSalesUnit(SalesUnitId.of(cmd.salesUnitId()))) { + case Failure(var err) -> { return Result.failure(err); } + case Success(var ignored) -> { } + } + + switch (articleRepository.save(article)) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(article); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/RemoveSupplier.java b/backend/src/main/java/de/effigenix/application/masterdata/RemoveSupplier.java index 0ee6fd5..9f08e4a 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/RemoveSupplier.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/RemoveSupplier.java @@ -2,13 +2,10 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.RemoveSupplierCommand; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -23,24 +20,25 @@ public class RemoveSupplier { public Result execute(RemoveSupplierCommand cmd, ActorId performedBy) { var articleId = ArticleId.of(cmd.articleId()); + Article article; switch (articleRepository.findById(articleId)) { - case Failure> f -> - { return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new ArticleError.ArticleNotFound(articleId)); } - Article article = s.value().get(); - article.removeSupplierReference(SupplierId.of(cmd.supplierId())); - - switch (articleRepository.save(article)) { - case Failure f2 -> - { return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(article); + article = opt.get(); } } + article.removeSupplierReference(SupplierId.of(cmd.supplierId())); + + switch (articleRepository.save(article)) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(article); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/SetFrameContract.java b/backend/src/main/java/de/effigenix/application/masterdata/SetFrameContract.java index 49b301b..2d05ce5 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/SetFrameContract.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/SetFrameContract.java @@ -3,13 +3,11 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.SetFrameContractCommand; import de.effigenix.domain.masterdata.*; import de.effigenix.shared.common.Money; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; -import java.util.stream.Collectors; +import java.util.ArrayList; import static de.effigenix.shared.common.Result.*; @@ -25,41 +23,51 @@ public class SetFrameContract { public Result execute(SetFrameContractCommand cmd, ActorId performedBy) { var customerId = CustomerId.of(cmd.customerId()); + Customer customer; switch (customerRepository.findById(customerId)) { - case Failure> f -> - { return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new CustomerError.CustomerNotFound(customerId)); } - Customer customer = s.value().get(); - - var lineItems = cmd.lineItems().stream() - .map(li -> new ContractLineItem( - ArticleId.of(li.articleId()), - Money.euro(li.agreedPrice()), - li.agreedQuantity(), - li.unit())) - .collect(Collectors.toList()); - - try { - var contract = FrameContract.create(cmd.validFrom(), cmd.validUntil(), cmd.rhythm(), lineItems); - var setResult = customer.setFrameContract(contract); - if (setResult.isFailure()) { - return Result.failure(setResult.unsafeGetError()); - } - } catch (IllegalArgumentException e) { - return Result.failure(new CustomerError.InvalidFrameContract(e.getMessage())); - } - - switch (customerRepository.save(customer)) { - case Failure f2 -> - { return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(customer); + customer = opt.get(); } } + + var lineItems = new ArrayList(); + for (var li : cmd.lineItems()) { + Money price; + switch (Money.tryEuro(li.agreedPrice())) { + case Failure(var msg) -> { return Result.failure(new CustomerError.ValidationFailure(msg)); } + case Success(var val) -> price = val; + } + + ContractLineItem item; + switch (ContractLineItem.create(ArticleId.of(li.articleId()), price, li.agreedQuantity(), li.unit())) { + case Failure(var msg) -> { return Result.failure(new CustomerError.ValidationFailure(msg)); } + case Success(var val) -> item = val; + } + lineItems.add(item); + } + + FrameContract contract; + switch (FrameContract.create(cmd.validFrom(), cmd.validUntil(), cmd.rhythm(), lineItems)) { + case Failure(var msg) -> { return Result.failure(new CustomerError.InvalidFrameContract(msg)); } + case Success(var val) -> contract = val; + } + + switch (customer.setFrameContract(contract)) { + case Failure(var err) -> { return Result.failure(err); } + case Success(var ignored) -> { } + } + + switch (customerRepository.save(customer)) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(customer); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/SetPreferences.java b/backend/src/main/java/de/effigenix/application/masterdata/SetPreferences.java index 68c7cd3..2d4cb4d 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/SetPreferences.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/SetPreferences.java @@ -2,13 +2,10 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.SetPreferencesCommand; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -23,24 +20,25 @@ public class SetPreferences { public Result execute(SetPreferencesCommand cmd, ActorId performedBy) { var customerId = CustomerId.of(cmd.customerId()); + Customer customer; switch (customerRepository.findById(customerId)) { - case Failure> f -> - { return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new CustomerError.CustomerNotFound(customerId)); } - Customer customer = s.value().get(); - customer.setPreferences(cmd.preferences()); - - switch (customerRepository.save(customer)) { - case Failure f2 -> - { return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(customer); + customer = opt.get(); } } + customer.setPreferences(cmd.preferences()); + + switch (customerRepository.save(customer)) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(customer); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/UpdateArticle.java b/backend/src/main/java/de/effigenix/application/masterdata/UpdateArticle.java index 62415ac..988a91d 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/UpdateArticle.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/UpdateArticle.java @@ -2,13 +2,10 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.UpdateArticleCommand; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -23,30 +20,36 @@ public class UpdateArticle { public Result execute(UpdateArticleCommand cmd, ActorId performedBy) { var articleId = ArticleId.of(cmd.articleId()); + Article article; switch (articleRepository.findById(articleId)) { - case Failure> f -> - { return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new ArticleError.ArticleNotFound(articleId)); } - Article article = s.value().get(); - - if (cmd.name() != null) { - article.rename(new ArticleName(cmd.name())); - } - if (cmd.categoryId() != null) { - article.changeCategory(ProductCategoryId.of(cmd.categoryId())); - } - - switch (articleRepository.save(article)) { - case Failure f2 -> - { return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(article); + article = opt.get(); } } + + if (cmd.name() != null) { + ArticleName name; + switch (ArticleName.of(cmd.name())) { + case Failure(var msg) -> { return Result.failure(new ArticleError.ValidationFailure(msg)); } + case Success(var val) -> name = val; + } + article.rename(name); + } + if (cmd.categoryId() != null) { + article.changeCategory(ProductCategoryId.of(cmd.categoryId())); + } + + switch (articleRepository.save(article)) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(article); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/UpdateCustomer.java b/backend/src/main/java/de/effigenix/application/masterdata/UpdateCustomer.java index 0768ebf..a215020 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/UpdateCustomer.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/UpdateCustomer.java @@ -6,8 +6,6 @@ import de.effigenix.shared.common.*; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -22,30 +20,54 @@ public class UpdateCustomer { public Result execute(UpdateCustomerCommand cmd, ActorId performedBy) { var customerId = CustomerId.of(cmd.customerId()); + Customer customer; switch (customerRepository.findById(customerId)) { - case Failure> f -> - { return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new CustomerError.CustomerNotFound(customerId)); } - Customer customer = s.value().get(); - - if (cmd.name() != null) { - customer.updateName(new CustomerName(cmd.name())); - } - customer.updateBillingAddress(new Address(cmd.street(), cmd.houseNumber(), cmd.postalCode(), cmd.city(), cmd.country())); - customer.updateContactInfo(new ContactInfo(cmd.phone(), cmd.email(), cmd.contactPerson())); - customer.updatePaymentTerms(new PaymentTerms(cmd.paymentDueDays(), cmd.paymentDescription())); - - switch (customerRepository.save(customer)) { - case Failure f2 -> - { return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(customer); + customer = opt.get(); } } + + if (cmd.name() != null) { + CustomerName name; + switch (CustomerName.of(cmd.name())) { + case Failure(var msg) -> { return Result.failure(new CustomerError.ValidationFailure(msg)); } + case Success(var val) -> name = val; + } + customer.updateName(name); + } + + Address address; + switch (Address.create(cmd.street(), cmd.houseNumber(), cmd.postalCode(), cmd.city(), cmd.country())) { + case Failure(var msg) -> { return Result.failure(new CustomerError.ValidationFailure(msg)); } + case Success(var val) -> address = val; + } + customer.updateBillingAddress(address); + + ContactInfo contactInfo; + switch (ContactInfo.create(cmd.phone(), cmd.email(), cmd.contactPerson())) { + case Failure(var msg) -> { return Result.failure(new CustomerError.ValidationFailure(msg)); } + case Success(var val) -> contactInfo = val; + } + customer.updateContactInfo(contactInfo); + + PaymentTerms paymentTerms; + switch (PaymentTerms.create(cmd.paymentDueDays(), cmd.paymentDescription())) { + case Failure(var msg) -> { return Result.failure(new CustomerError.ValidationFailure(msg)); } + case Success(var val) -> paymentTerms = val; + } + customer.updatePaymentTerms(paymentTerms); + + switch (customerRepository.save(customer)) { + case Failure(var err) -> + { return Result.failure(new CustomerError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(customer); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/UpdateProductCategory.java b/backend/src/main/java/de/effigenix/application/masterdata/UpdateProductCategory.java index c3155d3..7248fec 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/UpdateProductCategory.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/UpdateProductCategory.java @@ -2,13 +2,10 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.UpdateProductCategoryCommand; import de.effigenix.domain.masterdata.*; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -23,30 +20,36 @@ public class UpdateProductCategory { public Result execute(UpdateProductCategoryCommand cmd, ActorId performedBy) { var categoryId = ProductCategoryId.of(cmd.categoryId()); + ProductCategory category; switch (categoryRepository.findById(categoryId)) { - case Failure> f -> - { return Result.failure(new ProductCategoryError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new ProductCategoryError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new ProductCategoryError.CategoryNotFound(categoryId)); } - ProductCategory category = s.value().get(); - - if (cmd.name() != null) { - category.rename(new CategoryName(cmd.name())); - } - if (cmd.description() != null) { - category.updateDescription(cmd.description()); - } - - switch (categoryRepository.save(category)) { - case Failure f2 -> - { return Result.failure(new ProductCategoryError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(category); + category = opt.get(); } } + + if (cmd.name() != null) { + CategoryName name; + switch (CategoryName.of(cmd.name())) { + case Failure(var msg) -> { return Result.failure(new ProductCategoryError.ValidationFailure(msg)); } + case Success(var val) -> name = val; + } + category.rename(name); + } + if (cmd.description() != null) { + category.updateDescription(cmd.description()); + } + + switch (categoryRepository.save(category)) { + case Failure(var err) -> + { return Result.failure(new ProductCategoryError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(category); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/UpdateSalesUnitPrice.java b/backend/src/main/java/de/effigenix/application/masterdata/UpdateSalesUnitPrice.java index 037cce6..763f2ce 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/UpdateSalesUnitPrice.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/UpdateSalesUnitPrice.java @@ -3,13 +3,10 @@ package de.effigenix.application.masterdata; import de.effigenix.application.masterdata.command.UpdateSalesUnitPriceCommand; import de.effigenix.domain.masterdata.*; import de.effigenix.shared.common.Money; -import de.effigenix.shared.common.RepositoryError; import de.effigenix.shared.common.Result; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -24,29 +21,35 @@ public class UpdateSalesUnitPrice { public Result execute(UpdateSalesUnitPriceCommand cmd, ActorId performedBy) { var articleId = ArticleId.of(cmd.articleId()); + Article article; switch (articleRepository.findById(articleId)) { - case Failure> f -> - { return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new ArticleError.ArticleNotFound(articleId)); } - Article article = s.value().get(); - - var updateResult = article.updateSalesUnitPrice( - SalesUnitId.of(cmd.salesUnitId()), Money.euro(cmd.price())); - if (updateResult.isFailure()) { - return Result.failure(updateResult.unsafeGetError()); - } - - switch (articleRepository.save(article)) { - case Failure f2 -> - { return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(article); + article = opt.get(); } } + + Money price; + switch (Money.tryEuro(cmd.price())) { + case Failure(var msg) -> { return Result.failure(new ArticleError.ValidationFailure(msg)); } + case Success(var val) -> price = val; + } + + switch (article.updateSalesUnitPrice(SalesUnitId.of(cmd.salesUnitId()), price)) { + case Failure(var err) -> { return Result.failure(err); } + case Success(var ignored) -> { } + } + + switch (articleRepository.save(article)) { + case Failure(var err) -> + { return Result.failure(new ArticleError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(article); } } diff --git a/backend/src/main/java/de/effigenix/application/masterdata/UpdateSupplier.java b/backend/src/main/java/de/effigenix/application/masterdata/UpdateSupplier.java index 221a6b7..892ba35 100644 --- a/backend/src/main/java/de/effigenix/application/masterdata/UpdateSupplier.java +++ b/backend/src/main/java/de/effigenix/application/masterdata/UpdateSupplier.java @@ -6,8 +6,6 @@ import de.effigenix.shared.common.*; import de.effigenix.shared.security.ActorId; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - import static de.effigenix.shared.common.Result.*; @Transactional @@ -22,30 +20,54 @@ public class UpdateSupplier { public Result execute(UpdateSupplierCommand cmd, ActorId performedBy) { var supplierId = SupplierId.of(cmd.supplierId()); + Supplier supplier; switch (supplierRepository.findById(supplierId)) { - case Failure> f -> - { return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); } - case Success> s -> { - if (s.value().isEmpty()) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var opt) -> { + if (opt.isEmpty()) { return Result.failure(new SupplierError.SupplierNotFound(supplierId)); } - Supplier supplier = s.value().get(); - - if (cmd.name() != null) { - supplier.updateName(new SupplierName(cmd.name())); - } - supplier.updateAddress(new Address(cmd.street(), cmd.houseNumber(), cmd.postalCode(), cmd.city(), cmd.country())); - supplier.updateContactInfo(new ContactInfo(cmd.phone(), cmd.email(), cmd.contactPerson())); - supplier.updatePaymentTerms(new PaymentTerms(cmd.paymentDueDays(), cmd.paymentDescription())); - - switch (supplierRepository.save(supplier)) { - case Failure f2 -> - { return Result.failure(new SupplierError.RepositoryFailure(f2.error().message())); } - case Success ignored -> { } - } - - return Result.success(supplier); + supplier = opt.get(); } } + + if (cmd.name() != null) { + SupplierName name; + switch (SupplierName.of(cmd.name())) { + case Failure(var msg) -> { return Result.failure(new SupplierError.ValidationFailure(msg)); } + case Success(var val) -> name = val; + } + supplier.updateName(name); + } + + Address address; + switch (Address.create(cmd.street(), cmd.houseNumber(), cmd.postalCode(), cmd.city(), cmd.country())) { + case Failure(var msg) -> { return Result.failure(new SupplierError.ValidationFailure(msg)); } + case Success(var val) -> address = val; + } + supplier.updateAddress(address); + + ContactInfo contactInfo; + switch (ContactInfo.create(cmd.phone(), cmd.email(), cmd.contactPerson())) { + case Failure(var msg) -> { return Result.failure(new SupplierError.ValidationFailure(msg)); } + case Success(var val) -> contactInfo = val; + } + supplier.updateContactInfo(contactInfo); + + PaymentTerms paymentTerms; + switch (PaymentTerms.create(cmd.paymentDueDays(), cmd.paymentDescription())) { + case Failure(var msg) -> { return Result.failure(new SupplierError.ValidationFailure(msg)); } + case Success(var val) -> paymentTerms = val; + } + supplier.updatePaymentTerms(paymentTerms); + + switch (supplierRepository.save(supplier)) { + case Failure(var err) -> + { return Result.failure(new SupplierError.RepositoryFailure(err.message())); } + case Success(var ignored) -> { } + } + + return Result.success(supplier); } } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/Article.java b/backend/src/main/java/de/effigenix/domain/masterdata/Article.java index f1da90e..4b8d056 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/Article.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/Article.java @@ -55,7 +55,7 @@ public class Article { ProductCategoryId categoryId, SalesUnit initialSalesUnit ) { - if (name == null || articleNumber == null || categoryId == null || initialSalesUnit == null) { + if (initialSalesUnit == null) { return Result.failure(new ArticleError.MinimumSalesUnitRequired()); } var now = LocalDateTime.now(); diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/ArticleError.java b/backend/src/main/java/de/effigenix/domain/masterdata/ArticleError.java index 58aa523..1eabe7d 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/ArticleError.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/ArticleError.java @@ -40,6 +40,10 @@ public sealed interface ArticleError { @Override public String message() { return "Invalid price: " + reason; } } + record ValidationFailure(String message) implements ArticleError { + @Override public String code() { return "VALIDATION_ERROR"; } + } + record Unauthorized(String message) implements ArticleError { @Override public String code() { return "UNAUTHORIZED"; } } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/ArticleName.java b/backend/src/main/java/de/effigenix/domain/masterdata/ArticleName.java index c40e1d6..316ee2b 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/ArticleName.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/ArticleName.java @@ -1,5 +1,7 @@ package de.effigenix.domain.masterdata; +import de.effigenix.shared.common.Result; + public record ArticleName(String value) { public ArticleName { @@ -10,4 +12,12 @@ public record ArticleName(String value) { throw new IllegalArgumentException("ArticleName must not exceed 200 characters"); } } + + public static Result of(String value) { + try { + return Result.success(new ArticleName(value)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/ArticleNumber.java b/backend/src/main/java/de/effigenix/domain/masterdata/ArticleNumber.java index 1d2820a..9b9d7ad 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/ArticleNumber.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/ArticleNumber.java @@ -1,5 +1,7 @@ package de.effigenix.domain.masterdata; +import de.effigenix.shared.common.Result; + public record ArticleNumber(String value) { public ArticleNumber { @@ -10,4 +12,12 @@ public record ArticleNumber(String value) { throw new IllegalArgumentException("ArticleNumber must not exceed 50 characters"); } } + + public static Result of(String value) { + try { + return Result.success(new ArticleNumber(value)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/CategoryName.java b/backend/src/main/java/de/effigenix/domain/masterdata/CategoryName.java index 773d84e..1b67170 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/CategoryName.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/CategoryName.java @@ -1,5 +1,7 @@ package de.effigenix.domain.masterdata; +import de.effigenix.shared.common.Result; + public record CategoryName(String value) { public CategoryName { @@ -10,4 +12,12 @@ public record CategoryName(String value) { throw new IllegalArgumentException("CategoryName must not exceed 100 characters"); } } + + public static Result of(String value) { + try { + return Result.success(new CategoryName(value)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/ContractLineItem.java b/backend/src/main/java/de/effigenix/domain/masterdata/ContractLineItem.java index f367e44..f82f5fb 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/ContractLineItem.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/ContractLineItem.java @@ -1,6 +1,7 @@ package de.effigenix.domain.masterdata; import de.effigenix.shared.common.Money; +import de.effigenix.shared.common.Result; import java.math.BigDecimal; @@ -25,4 +26,13 @@ public record ContractLineItem( throw new IllegalArgumentException("Agreed quantity must be positive when set"); } } + + public static Result create( + ArticleId articleId, Money agreedPrice, BigDecimal agreedQuantity, Unit unit) { + try { + return Result.success(new ContractLineItem(articleId, agreedPrice, agreedQuantity, unit)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/Customer.java b/backend/src/main/java/de/effigenix/domain/masterdata/Customer.java index ce07a20..5752da6 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/Customer.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/Customer.java @@ -60,21 +60,18 @@ public class Customer { this.updatedAt = updatedAt; } - public static Result create( + public static Customer create( CustomerName name, CustomerType type, Address billingAddress, ContactInfo contactInfo, PaymentTerms paymentTerms ) { - if (name == null || type == null || billingAddress == null) { - return Result.failure(new CustomerError.CustomerNotFound(CustomerId.of("N/A"))); - } var now = LocalDateTime.now(); - return Result.success(new Customer( + return new Customer( CustomerId.generate(), name, type, billingAddress, contactInfo, paymentTerms, List.of(), null, Set.of(), CustomerStatus.ACTIVE, now, now - )); + ); } public static Customer reconstitute( diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/CustomerError.java b/backend/src/main/java/de/effigenix/domain/masterdata/CustomerError.java index da58701..e957c0a 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/CustomerError.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/CustomerError.java @@ -30,6 +30,10 @@ public sealed interface CustomerError { @Override public String message() { return "Duplicate line item for article '" + articleId.value() + "'"; } } + record ValidationFailure(String message) implements CustomerError { + @Override public String code() { return "VALIDATION_ERROR"; } + } + record Unauthorized(String message) implements CustomerError { @Override public String code() { return "UNAUTHORIZED"; } } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/CustomerName.java b/backend/src/main/java/de/effigenix/domain/masterdata/CustomerName.java index b27ab36..61de244 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/CustomerName.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/CustomerName.java @@ -1,5 +1,7 @@ package de.effigenix.domain.masterdata; +import de.effigenix.shared.common.Result; + public record CustomerName(String value) { public CustomerName { @@ -10,4 +12,12 @@ public record CustomerName(String value) { throw new IllegalArgumentException("CustomerName must not exceed 200 characters"); } } + + public static Result of(String value) { + try { + return Result.success(new CustomerName(value)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/DeliveryAddress.java b/backend/src/main/java/de/effigenix/domain/masterdata/DeliveryAddress.java index ec2e93a..e508c5a 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/DeliveryAddress.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/DeliveryAddress.java @@ -1,6 +1,7 @@ package de.effigenix.domain.masterdata; import de.effigenix.shared.common.Address; +import de.effigenix.shared.common.Result; /** * Value Object representing a labeled delivery address. @@ -17,4 +18,13 @@ public record DeliveryAddress( throw new IllegalArgumentException("Address must not be null"); } } + + public static Result create( + String label, Address address, String contactPerson, String deliveryNotes) { + try { + return Result.success(new DeliveryAddress(label, address, contactPerson, deliveryNotes)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/FrameContract.java b/backend/src/main/java/de/effigenix/domain/masterdata/FrameContract.java index a6ddcd3..c73dd3e 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/FrameContract.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/FrameContract.java @@ -1,6 +1,7 @@ package de.effigenix.domain.masterdata; import de.effigenix.shared.common.Money; +import de.effigenix.shared.common.Result; import java.time.LocalDate; import java.util.ArrayList; @@ -39,26 +40,26 @@ public class FrameContract { this.lineItems = new ArrayList<>(lineItems); } - public static FrameContract create( + public static Result create( LocalDate validFrom, LocalDate validUntil, DeliveryRhythm deliveryRhythm, List lineItems ) { if (validFrom != null && validUntil != null && validUntil.isBefore(validFrom)) { - throw new IllegalArgumentException("validUntil must not be before validFrom"); + return Result.failure("validUntil must not be before validFrom"); } if (lineItems == null || lineItems.isEmpty()) { - throw new IllegalArgumentException("FrameContract must have at least one line item"); + return Result.failure("FrameContract must have at least one line item"); } long distinctArticles = lineItems.stream() .map(ContractLineItem::articleId) .distinct() .count(); if (distinctArticles != lineItems.size()) { - throw new IllegalArgumentException("Duplicate ArticleIds in line items"); + return Result.failure("Duplicate ArticleIds in line items"); } - return new FrameContract(FrameContractId.generate(), validFrom, validUntil, deliveryRhythm, lineItems); + return Result.success(new FrameContract(FrameContractId.generate(), validFrom, validUntil, deliveryRhythm, lineItems)); } public static FrameContract reconstitute( diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/ProductCategory.java b/backend/src/main/java/de/effigenix/domain/masterdata/ProductCategory.java index 5656d82..7bd5642 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/ProductCategory.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/ProductCategory.java @@ -1,7 +1,5 @@ package de.effigenix.domain.masterdata; -import de.effigenix.shared.common.Result; - /** * Mini-Aggregate for product categories. * DB-based entity, dynamically extendable by users. @@ -18,11 +16,8 @@ public class ProductCategory { this.description = description; } - public static Result create(CategoryName name, String description) { - if (name == null) { - return Result.failure(new ProductCategoryError.InvalidCategoryName("Name must not be null")); - } - return Result.success(new ProductCategory(ProductCategoryId.generate(), name, description)); + public static ProductCategory create(CategoryName name, String description) { + return new ProductCategory(ProductCategoryId.generate(), name, description); } public static ProductCategory reconstitute(ProductCategoryId id, CategoryName name, String description) { diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/ProductCategoryError.java b/backend/src/main/java/de/effigenix/domain/masterdata/ProductCategoryError.java index a3068a3..8251668 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/ProductCategoryError.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/ProductCategoryError.java @@ -25,6 +25,10 @@ public sealed interface ProductCategoryError { @Override public String message() { return "Invalid category name: " + reason; } } + record ValidationFailure(String message) implements ProductCategoryError { + @Override public String code() { return "VALIDATION_ERROR"; } + } + record Unauthorized(String message) implements ProductCategoryError { @Override public String code() { return "UNAUTHORIZED"; } } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/QualityCertificate.java b/backend/src/main/java/de/effigenix/domain/masterdata/QualityCertificate.java index b37b0f8..84b0c00 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/QualityCertificate.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/QualityCertificate.java @@ -1,5 +1,7 @@ package de.effigenix.domain.masterdata; +import de.effigenix.shared.common.Result; + import java.time.LocalDate; /** @@ -22,6 +24,15 @@ public record QualityCertificate( } } + public static Result create( + String certificateType, String issuer, LocalDate validFrom, LocalDate validUntil) { + try { + return Result.success(new QualityCertificate(certificateType, issuer, validFrom, validUntil)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } + public boolean isExpired() { return validUntil != null && validUntil.isBefore(LocalDate.now()); } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/Supplier.java b/backend/src/main/java/de/effigenix/domain/masterdata/Supplier.java index e84d34b..5a6c869 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/Supplier.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/Supplier.java @@ -3,7 +3,6 @@ package de.effigenix.domain.masterdata; import de.effigenix.shared.common.Address; import de.effigenix.shared.common.ContactInfo; import de.effigenix.shared.common.PaymentTerms; -import de.effigenix.shared.common.Result; import java.time.LocalDateTime; import java.util.ArrayList; @@ -55,20 +54,17 @@ public class Supplier { this.updatedAt = updatedAt; } - public static Result create( + public static Supplier create( SupplierName name, Address address, ContactInfo contactInfo, PaymentTerms paymentTerms ) { - if (name == null || address == null || paymentTerms == null) { - return Result.failure(new SupplierError.SupplierNotFound(SupplierId.of("N/A"))); - } var now = LocalDateTime.now(); - return Result.success(new Supplier( + return new Supplier( SupplierId.generate(), name, address, contactInfo, paymentTerms, List.of(), null, SupplierStatus.ACTIVE, now, now - )); + ); } public static Supplier reconstitute( diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/SupplierError.java b/backend/src/main/java/de/effigenix/domain/masterdata/SupplierError.java index 0a85548..e47da61 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/SupplierError.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/SupplierError.java @@ -20,6 +20,15 @@ public sealed interface SupplierError { @Override public String message() { return "Invalid rating: " + reason; } } + record ValidationFailure(String message) implements SupplierError { + @Override public String code() { return "VALIDATION_ERROR"; } + } + + record CertificateNotFound(String certificateType) implements SupplierError { + @Override public String code() { return "CERTIFICATE_NOT_FOUND"; } + @Override public String message() { return "Certificate of type '" + certificateType + "' not found"; } + } + record Unauthorized(String message) implements SupplierError { @Override public String code() { return "UNAUTHORIZED"; } } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/SupplierName.java b/backend/src/main/java/de/effigenix/domain/masterdata/SupplierName.java index 8b67a6d..444e20a 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/SupplierName.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/SupplierName.java @@ -1,5 +1,7 @@ package de.effigenix.domain.masterdata; +import de.effigenix.shared.common.Result; + public record SupplierName(String value) { public SupplierName { @@ -10,4 +12,12 @@ public record SupplierName(String value) { throw new IllegalArgumentException("SupplierName must not exceed 200 characters"); } } + + public static Result of(String value) { + try { + return Result.success(new SupplierName(value)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } } diff --git a/backend/src/main/java/de/effigenix/domain/masterdata/SupplierRating.java b/backend/src/main/java/de/effigenix/domain/masterdata/SupplierRating.java index 0d6d8d0..78f6556 100644 --- a/backend/src/main/java/de/effigenix/domain/masterdata/SupplierRating.java +++ b/backend/src/main/java/de/effigenix/domain/masterdata/SupplierRating.java @@ -1,5 +1,7 @@ package de.effigenix.domain.masterdata; +import de.effigenix.shared.common.Result; + /** * Value Object representing a supplier rating with three scores (1-5). */ @@ -11,6 +13,14 @@ public record SupplierRating(int qualityScore, int deliveryScore, int priceScore validateScore("priceScore", priceScore); } + public static Result create(int qualityScore, int deliveryScore, int priceScore) { + try { + return Result.success(new SupplierRating(qualityScore, deliveryScore, priceScore)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } + public double averageScore() { return (qualityScore + deliveryScore + priceScore) / 3.0; } diff --git a/backend/src/main/java/de/effigenix/shared/common/Address.java b/backend/src/main/java/de/effigenix/shared/common/Address.java index 7e43cd9..f304a14 100644 --- a/backend/src/main/java/de/effigenix/shared/common/Address.java +++ b/backend/src/main/java/de/effigenix/shared/common/Address.java @@ -30,4 +30,13 @@ public record Address( } // houseNumber is optional (nullable) } + + public static Result create( + String street, String houseNumber, String postalCode, String city, String country) { + try { + return Result.success(new Address(street, houseNumber, postalCode, city, country)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } } diff --git a/backend/src/main/java/de/effigenix/shared/common/ContactInfo.java b/backend/src/main/java/de/effigenix/shared/common/ContactInfo.java index 674d79a..f84c3c3 100644 --- a/backend/src/main/java/de/effigenix/shared/common/ContactInfo.java +++ b/backend/src/main/java/de/effigenix/shared/common/ContactInfo.java @@ -17,6 +17,14 @@ public record ContactInfo( } } + public static Result create(String phone, String email, String contactPerson) { + try { + return Result.success(new ContactInfo(phone, email, contactPerson)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } + private static boolean isValidEmail(String email) { return email.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$"); } diff --git a/backend/src/main/java/de/effigenix/shared/common/Money.java b/backend/src/main/java/de/effigenix/shared/common/Money.java index 8a337e6..5225850 100644 --- a/backend/src/main/java/de/effigenix/shared/common/Money.java +++ b/backend/src/main/java/de/effigenix/shared/common/Money.java @@ -26,6 +26,14 @@ public record Money(BigDecimal amount, Currency currency) { return new Money(amount.setScale(2, RoundingMode.HALF_UP), Currency.getInstance("EUR")); } + public static Result tryEuro(BigDecimal amount) { + try { + return Result.success(euro(amount)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } + public static Money zero() { return new Money(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP), Currency.getInstance("EUR")); } diff --git a/backend/src/main/java/de/effigenix/shared/common/PaymentTerms.java b/backend/src/main/java/de/effigenix/shared/common/PaymentTerms.java index 371f33d..489e88d 100644 --- a/backend/src/main/java/de/effigenix/shared/common/PaymentTerms.java +++ b/backend/src/main/java/de/effigenix/shared/common/PaymentTerms.java @@ -11,4 +11,12 @@ public record PaymentTerms(int paymentDueDays, String description) { throw new IllegalArgumentException("Payment due days must not be negative"); } } + + public static Result create(int dueDays, String description) { + try { + return Result.success(new PaymentTerms(dueDays, description)); + } catch (IllegalArgumentException e) { + return Result.failure(e.getMessage()); + } + } }