WAQS: Modules dependency

7 reasons to use WAQS

WAQS documentation

 

Imagine that you have two modules: one for managing stock and one for ordering.

In ordering one you have a service method ConfirmOrder that create invoices and which also has to update stocks but without having stock entities in ordering model. So you have to use stock one in ordering module.

WAQS allows this kind of scenarios in specifications.

How to do it?

In specifications you can define a static property of type IStockService.

Then you can use it in your Ordering specification methods and WAQS will do the job on next generation.

So for example, this is the Stock model:

image

// Note that for concurrency aspect, UnitsInStock and UnitsOnOrder have ConcurrencyMode metadata set to Fixed.

Now we can add a Validation specification method:

public static Error ValidateStock(this ProductStock stock)
{
    if (stock.UnitsInStock < 0 || stock.UnitsOnOrder < 0)
        return new Error { Criticity = Criticity.Error, Message = "Stock can't be less than 0" };
    return null;
}


This is the Ordering model:



image



 





Now we can use these specifications:



public static void ConfirmOrder(this Order order, IOrderingService orderingService)
{
    var productIds = order.OrderDetails.Select(od => od.ProductId).Distinct();
    var stocks = StockService.ProductStocks.Where(ps => productIds.Contains(ps.Id)).ToList();
    foreach (var orderDetail in order.OrderDetails)
        stocks.First(s => s.Id == orderDetail.ProductId).UnitsInStock -= orderDetail.Quantity;
    StockService.SaveChanges();
    orderingService.Invoices.Add(MakeInvoice(order));
    orderingService.SaveChanges();
}

public static IStockService StockService { get; set; }

internal static Invoice MakeInvoice(this Order order)
{
    var customer = order.Customer;
    var invoice = new Invoice { Order = order, Customer = customer, CustomerCompanyName = customer.CompanyName,
CustomerContactName = customer.ContactName, Total = order.GetTotal() };
    foreach (var orderDetail in order.OrderDetails)
        invoice.InvoiceDetails.Add(new InvoiceDetail { OrderDetail = orderDetail, Quantity = orderDetail.Quantity,
UnitPrice = orderDetail.UnitPrice, Discount = orderDetail.Discount, Amount = orderDetail.GetAmount() });
    return invoice;
}

public static double GetAmount(this OrderDetail orderDetail)
{
    return orderDetail.UnitPrice * orderDetail.Quantity * (1 - orderDetail.Discount);
}

public static double GetTotal(this Order order)
{
    return order.OrderDetails.Sum(od => od.GetAmount());
}


So with this way we can have module dependency.



 



Note that when our validation test on UnitsInStock is done when you save changes on StockService from ConfirmOrder service method.

This entry was posted in 16868. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>