My code worked until I upgraded to Cuba 6.6 (although it probably is my fault).
I have an entity called “WorksOrder” that includes a composition “WorksOrderIngredients” with “RawMaterials” that is populated according to a recipe, and quantities that is determined by the mass required - amongst others
The views are defined as per the manual, on the WorksOrderEdit screen the datasources are defined as:
<dsContext>
<datasource id="worksOrderDs"
class="com.cernol.works.entity.WorksOrder"
view="worksOrder-view">
<collectionDatasource id="worksOrderPackingsDs"
property="worksOrderPackings"/>
<collectionDatasource id="worksOrderIngredientsDs"
property="worksOrderIngredients"/>
<collectionDatasource id="worksOrderLablesDs"
property="worksOrderLables"/>
</datasource>
<collectionDatasource id="problemListsDs"
class="com.cernol.works.entity.ProblemList"
refreshMode="NEVER"/>
</dsContext>
Then in the WorksOrderEdit.java I defined a listener on the “productPicker” which calls the following code:
public void resetIngredients() {
BigDecimal ingredientCost = BigDecimal.ZERO;
removeAllIngredients();
if (getItem().getProduct() != null) {
LoadContext<Product> loadContext = LoadContext.create(Product.class)
.setId(getItem().getProduct().getId())
.setView("product-view");
Product myProduct = dataManager.load(loadContext);
for (Formula formula : myProduct != null ? myProduct.getFormula() : null) {
WorksOrderIngredient orderIngredient = metadata.create(WorksOrderIngredient.class);
BigDecimal partsPer100 = formula.getPartsPer100();
orderIngredient.setWorksOrder(getItem());
orderIngredient.setSequenceNo(formula.getSequenceNo());
orderIngredient.setRawMaterial(formula.getRawMaterial());
orderIngredient.setMass(getItem().getMass()
.multiply(partsPer100)
.divide(BigDecimal.valueOf(100.0), 4, BigDecimal.ROUND_HALF_DOWN));
BigDecimal currentCost = stockItemService.getPointInTimeCost(
orderIngredient.getRawMaterial().getId(),
getItem().getDocumentOn());
orderIngredient.setKgCost(currentCost);
BigDecimal onhandQuantity = stockItemService.
getPointInTimeQuantity(orderIngredient.getRawMaterial().getId(), getItem().getDocumentOn());
if (onhandQuantity.compareTo(orderIngredient.getMass()) < 0) {
ProblemList problem = new ProblemList();
problem.setParent(getItem().getId());
problem.setDescription("Not enough stock: " +
orderIngredient.getRawMaterial().getInstanceName() +
"(" +
onhandQuantity +
" left)");
problemListsDs.addItem(problem);
}
worksOrderIngredientsDs.addItem(orderIngredient);
// worksOrderIngredientsDs.includeItem(orderIngredient);
ingredientCost = ingredientCost.add(orderIngredient.getLineCost());
}
}
getItem().setRawMaterialCost(ingredientCost);
}
private void removeAllIngredients() {
for (WorksOrderIngredient worksOrderIngredient : new ArrayList<>(worksOrderIngredientsDs.getItems())) {
worksOrderIngredientsDs.removeItem(worksOrderIngredient);
}
}
After the screen is complete (I use the extendedEditWindowActions) and you Save it - the data is written to the DB, but if you then “Save and Exit” duplicates the Ingredients…
If I just “Save and exit” and goes back, everything is fine.
If I use worksOrderIngredientsDs.includeItem instead of addItem I get a “During synchronization a new object was found through a relationship that was not marked cascade PERSIST” which points to a WorksOrderIngredient item… although my views are good as far as I can establish…
Any pointers would be appreciated.