1
0
Fork 0
mirror of https://github.com/s-frick/effigenix.git synced 2026-03-28 10:09:35 +01:00

refactor: konsistentes Result-basiertes Error-Handling im Master Data BC

VO-Factory-Methoden (of/create/tryEuro) für alle Value Objects eingeführt,
die intern IllegalArgumentException fangen und Result<String, T> 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.
This commit is contained in:
Sebastian Frick 2026-02-17 23:44:44 +01:00
parent b813fcbcaa
commit 6b341f217b
57 changed files with 853 additions and 658 deletions

View file

@ -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<ArticleError, Article> execute(ArticleId articleId, ActorId performedBy) {
Article article;
switch (articleRepository.findById(articleId)) {
case Failure<RepositoryError, Optional<Article>> f ->
{ return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Article>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<CustomerError, Customer> execute(CustomerId customerId, ActorId performedBy) {
Customer customer;
switch (customerRepository.findById(customerId)) {
case Failure<RepositoryError, Optional<Customer>> f ->
{ return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Customer>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<SupplierError, Supplier> execute(SupplierId supplierId, ActorId performedBy) {
Supplier supplier;
switch (supplierRepository.findById(supplierId)) {
case Failure<RepositoryError, Optional<Supplier>> f ->
{ return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Supplier>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new SupplierError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<SupplierError, Supplier> execute(AddCertificateCommand cmd, ActorId performedBy) {
var supplierId = SupplierId.of(cmd.supplierId());
Supplier supplier;
switch (supplierRepository.findById(supplierId)) {
case Failure<RepositoryError, Optional<Supplier>> f ->
{ return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Supplier>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new SupplierError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<CustomerError, Customer> execute(AddDeliveryAddressCommand cmd, ActorId performedBy) {
var customerId = CustomerId.of(cmd.customerId());
Customer customer;
switch (customerRepository.findById(customerId)) {
case Failure<RepositoryError, Optional<Customer>> f ->
{ return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Customer>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<ArticleError, Article> execute(AddSalesUnitCommand cmd, ActorId performedBy) {
var articleId = ArticleId.of(cmd.articleId());
Article article;
switch (articleRepository.findById(articleId)) {
case Failure<RepositoryError, Optional<Article>> f ->
{ return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Article>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<ArticleError, Article> execute(AssignSupplierCommand cmd, ActorId performedBy) {
var articleId = ArticleId.of(cmd.articleId());
Article article;
switch (articleRepository.findById(articleId)) {
case Failure<RepositoryError, Optional<Article>> f ->
{ return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Article>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<ArticleError, Article> execute(CreateArticleCommand cmd, ActorId performedBy) {
// Check uniqueness
switch (articleRepository.existsByArticleNumber(new ArticleNumber(cmd.articleNumber()))) {
case Failure<RepositoryError, Boolean> f ->
{ return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Boolean> 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<RepositoryError, Void> f ->
{ return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Void> ignored -> { }
case Failure(var err) ->
{ return Result.failure(new ArticleError.RepositoryFailure(err.message())); }
case Success(var ignored) -> { }
}
return Result.success(article);

View file

@ -18,33 +18,46 @@ public class CreateCustomer {
}
public Result<CustomerError, Customer> 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<RepositoryError, Boolean> f ->
{ return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Boolean> 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<RepositoryError, Void> f ->
{ return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Void> ignored -> { }
case Failure(var err) ->
{ return Result.failure(new CustomerError.RepositoryFailure(err.message())); }
case Success(var ignored) -> { }
}
return Result.success(customer);

View file

@ -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<ProductCategoryError, ProductCategory> 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<RepositoryError, Boolean> f ->
{ return Result.failure(new ProductCategoryError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Boolean> 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<RepositoryError, Void> f ->
{ return Result.failure(new ProductCategoryError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Void> ignored -> { }
case Failure(var err) ->
{ return Result.failure(new ProductCategoryError.RepositoryFailure(err.message())); }
case Success(var ignored) -> { }
}
return Result.success(category);

View file

@ -18,33 +18,46 @@ public class CreateSupplier {
}
public Result<SupplierError, Supplier> 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<RepositoryError, Boolean> f ->
{ return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Boolean> 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<RepositoryError, Void> f ->
{ return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Void> ignored -> { }
case Failure(var err) ->
{ return Result.failure(new SupplierError.RepositoryFailure(err.message())); }
case Success(var ignored) -> { }
}
return Result.success(supplier);

View file

@ -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<ArticleError, Article> execute(ArticleId articleId, ActorId performedBy) {
Article article;
switch (articleRepository.findById(articleId)) {
case Failure<RepositoryError, Optional<Article>> f ->
{ return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Article>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<CustomerError, Customer> execute(CustomerId customerId, ActorId performedBy) {
Customer customer;
switch (customerRepository.findById(customerId)) {
case Failure<RepositoryError, Optional<Customer>> f ->
{ return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Customer>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<SupplierError, Supplier> execute(SupplierId supplierId, ActorId performedBy) {
Supplier supplier;
switch (supplierRepository.findById(supplierId)) {
case Failure<RepositoryError, Optional<Supplier>> f ->
{ return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Supplier>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new SupplierError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<ProductCategoryError, Void> execute(ProductCategoryId categoryId, ActorId performedBy) {
// Check category exists
ProductCategory category;
switch (categoryRepository.findById(categoryId)) {
case Failure<RepositoryError, Optional<ProductCategory>> f ->
{ return Result.failure(new ProductCategoryError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<ProductCategory>> 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<RepositoryError, List<Article>> f2 ->
{ return Result.failure(new ProductCategoryError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, List<Article>> s2 -> {
if (!s2.value().isEmpty()) {
return Result.failure(new ProductCategoryError.CategoryInUse(categoryId));
}
}
}
// Delete
switch (categoryRepository.delete(category)) {
case Failure<RepositoryError, Void> f3 ->
{ return Result.failure(new ProductCategoryError.RepositoryFailure(f3.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<ArticleError, Article> execute(ArticleId articleId) {
return switch (articleRepository.findById(articleId)) {
case Failure<RepositoryError, Optional<Article>> f ->
Result.failure(new ArticleError.RepositoryFailure(f.error().message()));
case Success<RepositoryError, Optional<Article>> s ->
s.value()
.map(Result::<ArticleError, Article>success)
case Failure(var err) ->
Result.failure(new ArticleError.RepositoryFailure(err.message()));
case Success(var opt) ->
opt.map(Result::<ArticleError, Article>success)
.orElseGet(() -> Result.failure(new ArticleError.ArticleNotFound(articleId)));
};
}

View file

@ -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<CustomerError, Customer> execute(CustomerId customerId) {
return switch (customerRepository.findById(customerId)) {
case Failure<RepositoryError, Optional<Customer>> f ->
Result.failure(new CustomerError.RepositoryFailure(f.error().message()));
case Success<RepositoryError, Optional<Customer>> s ->
s.value()
.map(Result::<CustomerError, Customer>success)
case Failure(var err) ->
Result.failure(new CustomerError.RepositoryFailure(err.message()));
case Success(var opt) ->
opt.map(Result::<CustomerError, Customer>success)
.orElseGet(() -> Result.failure(new CustomerError.CustomerNotFound(customerId)));
};
}

View file

@ -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<SupplierError, Supplier> execute(SupplierId supplierId) {
return switch (supplierRepository.findById(supplierId)) {
case Failure<RepositoryError, Optional<Supplier>> f ->
Result.failure(new SupplierError.RepositoryFailure(f.error().message()));
case Success<RepositoryError, Optional<Supplier>> s ->
s.value()
.map(Result::<SupplierError, Supplier>success)
case Failure(var err) ->
Result.failure(new SupplierError.RepositoryFailure(err.message()));
case Success(var opt) ->
opt.map(Result::<SupplierError, Supplier>success)
.orElseGet(() -> Result.failure(new SupplierError.SupplierNotFound(supplierId)));
};
}

View file

@ -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<ArticleError, List<Article>> execute() {
return switch (articleRepository.findAll()) {
case Failure<RepositoryError, List<Article>> f ->
Result.failure(new ArticleError.RepositoryFailure(f.error().message()));
case Success<RepositoryError, List<Article>> 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<ArticleError, List<Article>> executeByCategory(ProductCategoryId categoryId) {
return switch (articleRepository.findByCategory(categoryId)) {
case Failure<RepositoryError, List<Article>> f ->
Result.failure(new ArticleError.RepositoryFailure(f.error().message()));
case Success<RepositoryError, List<Article>> 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<ArticleError, List<Article>> executeByStatus(ArticleStatus status) {
return switch (articleRepository.findByStatus(status)) {
case Failure<RepositoryError, List<Article>> f ->
Result.failure(new ArticleError.RepositoryFailure(f.error().message()));
case Success<RepositoryError, List<Article>> s ->
Result.success(s.value());
case Failure(var err) ->
Result.failure(new ArticleError.RepositoryFailure(err.message()));
case Success(var articles) ->
Result.success(articles);
};
}
}

View file

@ -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<CustomerError, List<Customer>> execute() {
return switch (customerRepository.findAll()) {
case Failure<RepositoryError, List<Customer>> f ->
Result.failure(new CustomerError.RepositoryFailure(f.error().message()));
case Success<RepositoryError, List<Customer>> 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<CustomerError, List<Customer>> executeByType(CustomerType type) {
return switch (customerRepository.findByType(type)) {
case Failure<RepositoryError, List<Customer>> f ->
Result.failure(new CustomerError.RepositoryFailure(f.error().message()));
case Success<RepositoryError, List<Customer>> 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<CustomerError, List<Customer>> executeByStatus(CustomerStatus status) {
return switch (customerRepository.findByStatus(status)) {
case Failure<RepositoryError, List<Customer>> f ->
Result.failure(new CustomerError.RepositoryFailure(f.error().message()));
case Success<RepositoryError, List<Customer>> s ->
Result.success(s.value());
case Failure(var err) ->
Result.failure(new CustomerError.RepositoryFailure(err.message()));
case Success(var customers) ->
Result.success(customers);
};
}
}

View file

@ -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<ProductCategoryError, List<ProductCategory>> execute() {
return switch (categoryRepository.findAll()) {
case Failure<RepositoryError, List<ProductCategory>> f ->
Result.failure(new ProductCategoryError.RepositoryFailure(f.error().message()));
case Success<RepositoryError, List<ProductCategory>> s ->
Result.success(s.value());
case Failure(var err) ->
Result.failure(new ProductCategoryError.RepositoryFailure(err.message()));
case Success(var categories) ->
Result.success(categories);
};
}
}

View file

@ -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<SupplierError, List<Supplier>> execute() {
return switch (supplierRepository.findAll()) {
case Failure<RepositoryError, List<Supplier>> f ->
Result.failure(new SupplierError.RepositoryFailure(f.error().message()));
case Success<RepositoryError, List<Supplier>> 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<SupplierError, List<Supplier>> executeByStatus(SupplierStatus status) {
return switch (supplierRepository.findByStatus(status)) {
case Failure<RepositoryError, List<Supplier>> f ->
Result.failure(new SupplierError.RepositoryFailure(f.error().message()));
case Success<RepositoryError, List<Supplier>> s ->
Result.success(s.value());
case Failure(var err) ->
Result.failure(new SupplierError.RepositoryFailure(err.message()));
case Success(var suppliers) ->
Result.success(suppliers);
};
}
}

View file

@ -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<SupplierError, Supplier> execute(RateSupplierCommand cmd, ActorId performedBy) {
var supplierId = SupplierId.of(cmd.supplierId());
Supplier supplier;
switch (supplierRepository.findById(supplierId)) {
case Failure<RepositoryError, Optional<Supplier>> f ->
{ return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Supplier>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new SupplierError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<SupplierError, Supplier> execute(RemoveCertificateCommand cmd, ActorId performedBy) {
var supplierId = SupplierId.of(cmd.supplierId());
Supplier supplier;
switch (supplierRepository.findById(supplierId)) {
case Failure<RepositoryError, Optional<Supplier>> f ->
{ return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Supplier>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new SupplierError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<CustomerError, Customer> execute(RemoveDeliveryAddressCommand cmd, ActorId performedBy) {
var customerId = CustomerId.of(cmd.customerId());
Customer customer;
switch (customerRepository.findById(customerId)) {
case Failure<RepositoryError, Optional<Customer>> f ->
{ return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Customer>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<CustomerError, Customer> execute(CustomerId customerId, ActorId performedBy) {
Customer customer;
switch (customerRepository.findById(customerId)) {
case Failure<RepositoryError, Optional<Customer>> f ->
{ return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Customer>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<ArticleError, Article> execute(RemoveSalesUnitCommand cmd, ActorId performedBy) {
var articleId = ArticleId.of(cmd.articleId());
Article article;
switch (articleRepository.findById(articleId)) {
case Failure<RepositoryError, Optional<Article>> f ->
{ return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Article>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<ArticleError, Article> execute(RemoveSupplierCommand cmd, ActorId performedBy) {
var articleId = ArticleId.of(cmd.articleId());
Article article;
switch (articleRepository.findById(articleId)) {
case Failure<RepositoryError, Optional<Article>> f ->
{ return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Article>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<CustomerError, Customer> execute(SetFrameContractCommand cmd, ActorId performedBy) {
var customerId = CustomerId.of(cmd.customerId());
Customer customer;
switch (customerRepository.findById(customerId)) {
case Failure<RepositoryError, Optional<Customer>> f ->
{ return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Customer>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> ignored -> { }
}
return Result.success(customer);
customer = opt.get();
}
}
var lineItems = new ArrayList<ContractLineItem>();
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);
}
}

View file

@ -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<CustomerError, Customer> execute(SetPreferencesCommand cmd, ActorId performedBy) {
var customerId = CustomerId.of(cmd.customerId());
Customer customer;
switch (customerRepository.findById(customerId)) {
case Failure<RepositoryError, Optional<Customer>> f ->
{ return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Customer>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<ArticleError, Article> execute(UpdateArticleCommand cmd, ActorId performedBy) {
var articleId = ArticleId.of(cmd.articleId());
Article article;
switch (articleRepository.findById(articleId)) {
case Failure<RepositoryError, Optional<Article>> f ->
{ return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Article>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<CustomerError, Customer> execute(UpdateCustomerCommand cmd, ActorId performedBy) {
var customerId = CustomerId.of(cmd.customerId());
Customer customer;
switch (customerRepository.findById(customerId)) {
case Failure<RepositoryError, Optional<Customer>> f ->
{ return Result.failure(new CustomerError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Customer>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new CustomerError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<ProductCategoryError, ProductCategory> execute(UpdateProductCategoryCommand cmd, ActorId performedBy) {
var categoryId = ProductCategoryId.of(cmd.categoryId());
ProductCategory category;
switch (categoryRepository.findById(categoryId)) {
case Failure<RepositoryError, Optional<ProductCategory>> f ->
{ return Result.failure(new ProductCategoryError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<ProductCategory>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new ProductCategoryError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<ArticleError, Article> execute(UpdateSalesUnitPriceCommand cmd, ActorId performedBy) {
var articleId = ArticleId.of(cmd.articleId());
Article article;
switch (articleRepository.findById(articleId)) {
case Failure<RepositoryError, Optional<Article>> f ->
{ return Result.failure(new ArticleError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Article>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new ArticleError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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<SupplierError, Supplier> execute(UpdateSupplierCommand cmd, ActorId performedBy) {
var supplierId = SupplierId.of(cmd.supplierId());
Supplier supplier;
switch (supplierRepository.findById(supplierId)) {
case Failure<RepositoryError, Optional<Supplier>> f ->
{ return Result.failure(new SupplierError.RepositoryFailure(f.error().message())); }
case Success<RepositoryError, Optional<Supplier>> 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<RepositoryError, Void> f2 ->
{ return Result.failure(new SupplierError.RepositoryFailure(f2.error().message())); }
case Success<RepositoryError, Void> 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);
}
}

View file

@ -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();

View file

@ -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"; }
}

View file

@ -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<String, ArticleName> of(String value) {
try {
return Result.success(new ArticleName(value));
} catch (IllegalArgumentException e) {
return Result.failure(e.getMessage());
}
}
}

View file

@ -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<String, ArticleNumber> of(String value) {
try {
return Result.success(new ArticleNumber(value));
} catch (IllegalArgumentException e) {
return Result.failure(e.getMessage());
}
}
}

View file

@ -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<String, CategoryName> of(String value) {
try {
return Result.success(new CategoryName(value));
} catch (IllegalArgumentException e) {
return Result.failure(e.getMessage());
}
}
}

View file

@ -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<String, ContractLineItem> 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());
}
}
}

View file

@ -60,21 +60,18 @@ public class Customer {
this.updatedAt = updatedAt;
}
public static Result<CustomerError, Customer> 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(

View file

@ -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"; }
}

View file

@ -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<String, CustomerName> of(String value) {
try {
return Result.success(new CustomerName(value));
} catch (IllegalArgumentException e) {
return Result.failure(e.getMessage());
}
}
}

View file

@ -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<String, DeliveryAddress> 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());
}
}
}

View file

@ -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<String, FrameContract> create(
LocalDate validFrom,
LocalDate validUntil,
DeliveryRhythm deliveryRhythm,
List<ContractLineItem> 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(

View file

@ -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<ProductCategoryError, ProductCategory> 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) {

View file

@ -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"; }
}

View file

@ -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<String, QualityCertificate> 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());
}

View file

@ -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<SupplierError, Supplier> 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(

View file

@ -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"; }
}

View file

@ -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<String, SupplierName> of(String value) {
try {
return Result.success(new SupplierName(value));
} catch (IllegalArgumentException e) {
return Result.failure(e.getMessage());
}
}
}

View file

@ -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<String, SupplierRating> 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;
}

View file

@ -30,4 +30,13 @@ public record Address(
}
// houseNumber is optional (nullable)
}
public static Result<String, Address> 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());
}
}
}

View file

@ -17,6 +17,14 @@ public record ContactInfo(
}
}
public static Result<String, ContactInfo> 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,}$");
}

View file

@ -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<String, Money> 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"));
}

View file

@ -11,4 +11,12 @@ public record PaymentTerms(int paymentDueDays, String description) {
throw new IllegalArgumentException("Payment due days must not be negative");
}
}
public static Result<String, PaymentTerms> create(int dueDays, String description) {
try {
return Result.success(new PaymentTerms(dueDays, description));
} catch (IllegalArgumentException e) {
return Result.failure(e.getMessage());
}
}
}