DDD modify child object through parent - domain-driven-design

I'm writing a monthly expenditure application where you add 'expenditures' to a month, these expenditures contain a description of what the expenditure is and the amount. For example you may have April 2015, and within that you have as expenditure items such as:
New tires for car $200
Utility bills $350
etc...
I've written the following, thus allowing you to add items to the month
class ExpenditureMonth
{
public function addExpenditureItem(String description, Money amount)
{
items.add(new ExpenditureItem(this, description, amount));
}
}
Therefore the object creation of ExpenditureItem happens within ExpenditureMonth. An expenditure month can contain many items.
When the account holder has paid for an item, it needs to be marked as paid.
How would I set an item as paid?
My only thinking is set an identifier for an ExpenditureItem and pass this instance to the addExpenditureItem method but this doesn't seem right to me?!

I had a similar question before (please read the answers).
In DDD, the parent or the aggregate root changes depending on the bounded context. So in your case, this is your context:
When the account holder has paid for an item, it needs to be marked as paid.
For that particular context, the expenditure item is now the aggregate root, and now it requires ID to be identified on its own. Setting up an ID or a GUID is the generally accepted solution, I don't think it is reliable to uniquely identify an object without a proper key.
However, if the case is "the account holder paid for all his monthly unpaid expenditures (or all unpaid expenditures)", then for that context the aggregate root is your MonthlyExpenditure.

Related

Relationship between collections in mongodb

How can we do relational update queries in mongodb.
We have the following scenario:
In a bank the deposits of the clients are managed, once a certain
period of time is fulfilled the bank returns the deposit to the
clients plus the accrued interest, a client can have several deposits.
we create the client's collection, with his name, and what he has
available to withdraw, we create the deposit collection, with the
amount, the interest rate, and we join it to the client's model by the
client's id from a clientId field. Every 24 hours the bank updates all
user accounts, if the deposit creation date is less than two years,
the user's interest is updated, if the date is equal to 2 years a new
field is added to the deposit (expired: true), and to the client's
collection in the available field is added, what was already
accumulated, the interest, plus the amount of the deposit. To give a
solution I have tried to obtain all the deposits, I save them in an
object and I go through it with the map property. Inside the map I try
to update the clients that have expired deposits, however, only the
last element that runs through the map is being updated.
What would be the best solution to this problem. I clarify that I am using mongoose and nodejs.

NetSuite Saved Search Showing Inside Sales Rep If There Is One

I'm trying to do a saved search in NetSuite that returns all of the customers in a particular state and, for those which have an Inside Sales Rep, the name of that rep.
But if I specify Sales Team Role = Inside Sales Rep in the criteria, the result only contains customers who have an Inside Sales Rep (and we have some that do not).
If I don't specify the Sales Team Role in the criteria but list Sales Team Role and Sales Team Member in the Results, then I get every customer, but a row for every sales team member, with their role - so multiple lines per customer. I don't want that.
I just want a line in the results for each customer and, if there is an Inside Sales Rep on that customer, that person's name.
Any suggestions?
Basically, you need a left join ;).
Instead, you can use a formula to return either the sales rep if the role is inside sales, or null, or null if there is no sales rep. Then you aggregate it using maximum.
Or you can use the rank function (using the formula above within the rank syntax), selecting where rank = 1. This allows you to save your aggregation for when you need it, at the expense of clarity.

How to handle a Value Object referencing an Entity?

I have just started to look into DDD, and is trying to look into some scenarios.
I have a Product (Entity) with a ProductName (Value Object) and a ProductPrice (Value Object). The Product Price then have an amount (decimal) and a Currency.
My issue is regarding the Currency. First I designed this as a Value Object, but it should be possible to add new Currencies to the system, and it should also be possible to list them in some kind of GUI. In other words it seems like I need a repository for Currencies. In my mind this means that Currency should be designed as an Entity.
But, now I have a Value Object (Product Price) referencing an entity (Currency). How should this be handled? My guess (I am not sure) is that I remove the reference to the currency entity inside the Product Price, and instead adds the Id of the Currency (USD, EUR etc). The Currency then becomes its own aggregate.
Is this a valid and preferred design in DDD, or should this be done in some other way?
In the original DDD book, Evans did discuss the possibility of having values that can reference entities. (Chapter 5: "VALUE OBJECTS can even reference ENTITIES")
I think everybody, by and large, has abandoned that practice. Immutability is too powerful an idea. Values will normally only reference other values. Instead of referencing a entity, we include the entity identifier.
So the usual solution would be that you model the currency code as a value, and store (copies of) that value in your Price value.
The Currency then becomes its own aggregate.
I would not expect this to happen. How does a currency change over time?
What I think you will find is that currency is fairly static: the thing that changes over time is the CurrencyExchange -- which currencies are currently listed? what is the exchange rate today? What was the exchange rate two years ago? Which political units prefer this currency as of Thursday?
Currencies are closer in nature to units of measure: feet, inches, meters, pounds, liters seconds. Meters are a unit of measure in the dimension of length; currency is a unit of measure in the dimension of "money".
how do you handle that new currencies can be added to the system, and how can you select between currencies in the GUI?
There are two possible answers to that.
If your domain is the authority for which currencies are active in the system, then the currency registry/currency exchange should be a first class entity in your domain model, and manages the process of change to the listed currencies.
If your domain is not the authority, then you just cache a copy of the information you get from the authority. Caches are typically CRUD (PUT, GET, DELETE, maybe PATCH).

Populate VO in drop down list in UI

I have Person class which is root of its aggregate, this aggregate also contains country and state province as vo.
{Person, Country, StateProvince} - > Person is root aggregate.
//
Public Person(string name, string country, state province,{other params}){}
// But now i am facing problem in UI, how will i populate Dropdown for Country and Stateprovince, through person because it is root aggregate, but i don't want any person's assigned Country or Stateprovince but i want list of all countries and their Stateprovince, so that user choose one from them
Do i manually create table for country and stateprovince and fill them with all values manually.If yes, then how will i get values from those tables in ddd .
Your model is trying to tell you something.
Country and StateProvince are probably not part of the Person Aggregate.
Remember the very handy "delete test" for an aggregate, ask if I delete this person do I also delete their country and StateProvince? I live in Canada, and you remove me from your system are you also going to delete the country Canada from your system as well?
No, you would not. You have two separate aggregates here Person and Location which would contain the Aggregate of {Country, StateProvince} If you delete a country you would very likely also delete all the states or provinces contained within it as well.
Just because Person references a class or has-a class doesn't make all the references part of that aggregate. Location is very common aggregate in many systems and regularly stands on it's own.
You should have a Person Repository that utilizes a LocationRepository and have the UI directly call the LocationRepository to obtain Location Aggregates.
You would populate your country and state province from different tables. You would then fill the drop downs from these tables. When working with a specific Person entity which has already got Country and StateProvince assigned you would bind them with master tables through id.
Hope that helps.

saving a to-many-relationship

I'm starting to learn and practice some CoreData, with no programming experience.
After searching in Web, looking for Apple samples and reading some books, I´m still stucked in one point.
I have two entities (Expenses and Month) with reciprocal relationships called "monthsOfExpense" and "expensesOfmonth" and I'm showing in a tableView the expenses of a single month.
My problem is to insert new expenses and save them: I've a view to insert new expenses where the user can insert the name of Expense, the value and the months that expense is valid (associated with the monthsOfExpense relationship, i hope).
I'm ok saving the name and the value of Expense entity, taking the string and NSDecimal number from the textFields.
My problem is how to associate that expense to a particular or several months? How can I save a textField.text as a relationship, indicating to what month an Expense belongs?
I'm starting with a textField where the user can insert a month, assuming that an Expense is valid for one month only (for learning purposes and simplification).
My idea is to allow the user to select several months (using maybe another tableView with selectable months) and association of an Expense to different months.
I know that a relationship comes as a NSSet, but I'm not being competent to save the attributes and the relationship from a View, at the same time.
Hope was cleared and many thanks in advance for trying to help.
OK. In Core data, you define your "Expense" entity, create a relationship to "Month" entity. Now create class files for these 2 entities. Then you use it by
Expense *expense1 = [NSEntityDescription insertNewObjectForEntityName:#"Expense" ....
Month *month1 = [context executeFetchRequest:......];
expense1.month = month1;
...
[context save];
In your situation, you can predefine 12 "Month" objects, giving the month name as the text property.
Then you can lookup these month objects using NSFetchRequest. Add the relevant month objects to your expense using
[expense addMonthObject:month]
Then save your managed object context.
You message the managed object for its mutableSetValueForKey:RelationshipKey,
then you add the to-many managed objects to that set. CoreData completes the other half of the relationship data.

Resources