use of org.apache.ofbiz.entity.model.ModelKeyMap in project ofbiz-framework by apache.
the class ProductUtilServices method makeStandAloneFromSingleVariantVirtuals.
public static Map<String, Object> makeStandAloneFromSingleVariantVirtuals(DispatchContext dctx, Map<String, ? extends Object> context) {
Delegator delegator = dctx.getDelegator();
LocalDispatcher dispatcher = dctx.getDispatcher();
GenericValue userLogin = (GenericValue) context.get("userLogin");
Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
Locale locale = (Locale) context.get("locale");
String errMsg = null;
Debug.logInfo("Starting makeStandAloneFromSingleVariantVirtuals", module);
DynamicViewEntity dve = new DynamicViewEntity();
dve.addMemberEntity("PVIRT", "Product");
dve.addMemberEntity("PVA", "ProductAssoc");
dve.addViewLink("PVIRT", "PVA", Boolean.FALSE, UtilMisc.toList(new ModelKeyMap("productId", "productId")));
dve.addAlias("PVIRT", "productId", null, null, null, Boolean.TRUE, null);
dve.addAlias("PVIRT", "salesDiscontinuationDate", null, null, null, null, null);
dve.addAlias("PVA", "productAssocTypeId", null, null, null, null, null);
dve.addAlias("PVA", "fromDate", null, null, null, null, null);
dve.addAlias("PVA", "thruDate", null, null, null, null, null);
dve.addAlias("PVA", "productIdToCount", "productIdTo", null, null, null, "count-distinct");
EntityCondition condition = EntityCondition.makeCondition(UtilMisc.toList(EntityCondition.makeCondition("productAssocTypeId", EntityOperator.EQUALS, "PRODUCT_VARIANT"), EntityCondition.makeCondition(EntityCondition.makeCondition("salesDiscontinuationDate", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("salesDiscontinuationDate", EntityOperator.GREATER_THAN, nowTimestamp))), EntityOperator.AND);
EntityCondition havingCond = EntityCondition.makeCondition("productIdToCount", EntityOperator.EQUALS, Long.valueOf(1));
EntityQuery eq = EntityQuery.use(delegator).select("productId", "productIdToCount").from(dve).where(condition).having(havingCond);
try (EntityListIterator eliOne = eq.queryIterator()) {
List<GenericValue> valueList = eliOne.getCompleteList();
Debug.logInfo("Found " + valueList.size() + " virtual products with one variant to turn into a stand alone product.", module);
int numWithOneOnly = 0;
for (GenericValue value : valueList) {
// has only one variant period, is it valid? should already be discontinued if not
String productId = value.getString("productId");
List<GenericValue> paList = EntityQuery.use(delegator).from("ProductAssoc").where("productId", productId, "productAssocTypeId", "PRODUCT_VARIANT").filterByDate().queryList();
// verify the query; tested on a bunch, looks good
if (paList.size() != 1) {
Debug.logInfo("Virtual product with ID " + productId + " should have 1 assoc, has " + paList.size(), module);
} else {
// for all virtuals with one variant move all info from virtual to variant and remove virtual, make variant as not a variant
dispatcher.runSync("mergeVirtualWithSingleVariant", UtilMisc.<String, Object>toMap("productId", productId, "removeOld", Boolean.TRUE, "userLogin", userLogin));
numWithOneOnly++;
if (numWithOneOnly % 100 == 0) {
Debug.logInfo("Made " + numWithOneOnly + " virtual products with only one valid variant stand-alone products.", module);
}
}
}
EntityCondition conditionWithDates = EntityCondition.makeCondition(UtilMisc.toList(EntityCondition.makeCondition("productAssocTypeId", EntityOperator.EQUALS, "PRODUCT_VARIANT"), EntityCondition.makeCondition(EntityCondition.makeCondition("salesDiscontinuationDate", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("salesDiscontinuationDate", EntityOperator.GREATER_THAN, nowTimestamp)), EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, nowTimestamp), EntityCondition.makeCondition(EntityCondition.makeCondition("thruDate", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("thruDate", EntityOperator.GREATER_THAN_EQUAL_TO, nowTimestamp))), EntityOperator.AND);
eq = EntityQuery.use(delegator).select("productId", "productIdToCount").from(dve).where(conditionWithDates).having(havingCond);
try (EntityListIterator eliMulti = eq.queryIterator()) {
List<GenericValue> valueMultiList = eliMulti.getCompleteList();
Debug.logInfo("Found " + valueMultiList.size() + " virtual products with one VALID variant to pull the variant from to make a stand alone product.", module);
int numWithOneValid = 0;
for (GenericValue value : valueMultiList) {
// has only one valid variant
String productId = value.getString("productId");
List<GenericValue> paList = EntityQuery.use(delegator).from("ProductAssoc").where("productId", productId, "productAssocTypeId", "PRODUCT_VARIANT").filterByDate().queryList();
// verify the query; tested on a bunch, looks good
if (paList.size() != 1) {
Debug.logInfo("Virtual product with ID " + productId + " should have 1 assoc, has " + paList.size(), module);
} else {
// for all virtuals with one valid variant move info from virtual to variant, put variant in categories from virtual, remove virtual from all categories but leave "family" otherwise intact, mark variant as not a variant
dispatcher.runSync("mergeVirtualWithSingleVariant", UtilMisc.<String, Object>toMap("productId", productId, "removeOld", Boolean.FALSE, "userLogin", userLogin));
numWithOneValid++;
if (numWithOneValid % 100 == 0) {
Debug.logInfo("Made " + numWithOneValid + " virtual products with one valid variant stand-alone products.", module);
}
}
}
Debug.logInfo("Found virtual products with one valid variant: " + numWithOneValid + ", with one variant only: " + numWithOneOnly, module);
} catch (GenericEntityException e) {
Map<String, String> messageMap = UtilMisc.toMap("errMessage", e.toString());
errMsg = UtilProperties.getMessage(resourceError, "productutilservices.entity_error_running_makeStandAloneFromSingleVariantVirtuals", messageMap, locale);
Debug.logError(e, errMsg, module);
return ServiceUtil.returnError(errMsg);
}
} catch (GenericEntityException | GenericServiceException e) {
Map<String, String> messageMap = UtilMisc.toMap("errMessage", e.toString());
errMsg = UtilProperties.getMessage(resourceError, "productutilservices.entity_error_running_makeStandAloneFromSingleVariantVirtuals", messageMap, locale);
Debug.logError(e, errMsg, module);
return ServiceUtil.returnError(errMsg);
}
return ServiceUtil.returnSuccess();
}
use of org.apache.ofbiz.entity.model.ModelKeyMap in project ofbiz-framework by apache.
the class GenericDelegator method getRelatedOne.
/* (non-Javadoc)
* @see org.apache.ofbiz.entity.Delegator#getRelatedOne(java.lang.String, org.apache.ofbiz.entity.GenericValue, boolean)
*/
@Override
public GenericValue getRelatedOne(String relationName, GenericValue value, boolean useCache) throws GenericEntityException {
ModelRelation relation = value.getModelEntity().getRelation(relationName);
if (relation == null) {
throw new GenericModelException("Could not find relation for relationName: " + relationName + " for value " + value);
}
if (!"one".equals(relation.getType()) && !"one-nofk".equals(relation.getType())) {
throw new GenericModelException("Relation is not a 'one' or a 'one-nofk' relation: " + relationName + " of entity " + value.getEntityName());
}
Map<String, Object> fields = new HashMap<>();
for (ModelKeyMap keyMap : relation.getKeyMaps()) {
fields.put(keyMap.getRelFieldName(), value.get(keyMap.getFieldName()));
}
return this.findOne(relation.getRelEntityName(), fields, useCache);
}
use of org.apache.ofbiz.entity.model.ModelKeyMap in project ofbiz-framework by apache.
the class GenericDelegator method removeRelated.
/* (non-Javadoc)
* @see org.apache.ofbiz.entity.Delegator#removeRelated(java.lang.String, org.apache.ofbiz.entity.GenericValue)
*/
@Override
public int removeRelated(String relationName, GenericValue value) throws GenericEntityException {
ModelEntity modelEntity = value.getModelEntity();
ModelRelation relation = modelEntity.getRelation(relationName);
if (relation == null) {
throw new GenericModelException("Could not find relation for relationName: " + relationName + " for value " + value);
}
Map<String, Object> fields = new HashMap<>();
for (ModelKeyMap keyMap : relation.getKeyMaps()) {
fields.put(keyMap.getRelFieldName(), value.get(keyMap.getFieldName()));
}
return this.removeByAnd(relation.getRelEntityName(), fields);
}
use of org.apache.ofbiz.entity.model.ModelKeyMap in project ofbiz-framework by apache.
the class GenericDelegator method getRelatedDummyPK.
/* (non-Javadoc)
* @see org.apache.ofbiz.entity.Delegator#getRelatedDummyPK(java.lang.String, java.util.Map, org.apache.ofbiz.entity.GenericValue)
*/
@Override
public GenericPK getRelatedDummyPK(String relationName, Map<String, ? extends Object> byAndFields, GenericValue value) throws GenericEntityException {
ModelEntity modelEntity = value.getModelEntity();
ModelRelation relation = modelEntity.getRelation(relationName);
if (relation == null) {
throw new GenericModelException("Could not find relation for relationName: " + relationName + " for value " + value);
}
ModelEntity relatedEntity = getModelReader().getModelEntity(relation.getRelEntityName());
// put the byAndFields (if not null) into the hash map first,
// they will be overridden by value's fields if over-specified this is important for security and cleanliness
Map<String, Object> fields = new HashMap<>();
if (byAndFields != null) {
fields.putAll(byAndFields);
}
for (ModelKeyMap keyMap : relation.getKeyMaps()) {
fields.put(keyMap.getRelFieldName(), value.get(keyMap.getFieldName()));
}
return GenericPK.create(this, relatedEntity, fields);
}
use of org.apache.ofbiz.entity.model.ModelKeyMap in project ofbiz-framework by apache.
the class GenericDAO method singleUpdateView.
/* ====================================================================== */
/* ====================================================================== */
/**
* Try to update the given ModelViewEntity by trying to insert/update on the entities of which the view is composed.
*
* Works fine with standard O/R mapped models, but has some restrictions meeting more complicated view entities.
* <li>A direct link is required, which means that one of the ModelViewLink field entries must have a value found
* in the given view entity, for each ModelViewLink</li>
* <li>For now, each member entity is updated iteratively, so if eg. the second member entity fails to update,
* the first is written although. See code for details. Try to use "clean" views, until code is more robust ...</li>
* <li>For now, aliased field names in views are not processed correctly, I guess. To be honest, I did not
* find out how to construct such a view - so view fieldnames must have same named fields in member entities.</li>
* <li>A new exception, e.g. GenericViewNotUpdatable, should be defined and thrown if the update fails</li>
*/
private int singleUpdateView(GenericEntity entity, ModelViewEntity modelViewEntity, List<ModelField> fieldsToSave, SQLProcessor sqlP) throws GenericEntityException {
Delegator delegator = entity.getDelegator();
int retVal = 0;
ModelEntity memberModelEntity = null;
// Construct insert/update for each model entity
for (ModelViewEntity.ModelMemberEntity modelMemberEntity : modelViewEntity.getMemberModelMemberEntities().values()) {
String meName = modelMemberEntity.getEntityName();
String meAlias = modelMemberEntity.getEntityAlias();
if (Debug.verboseOn())
Debug.logVerbose("[singleUpdateView]: Processing MemberEntity " + meName + " with Alias " + meAlias, module);
try {
memberModelEntity = delegator.getModelReader().getModelEntity(meName);
} catch (GenericEntityException e) {
throw new GenericEntityException("Failed to get model entity for " + meName, e);
}
Map<String, Object> findByMap = new HashMap<String, Object>();
// Now iterate the ModelViewLinks to construct the "WHERE" part for update/insert
Iterator<ModelViewEntity.ModelViewLink> linkIter = modelViewEntity.getViewLinksIterator();
while (linkIter != null && linkIter.hasNext()) {
ModelViewEntity.ModelViewLink modelViewLink = linkIter.next();
if (modelViewLink.getEntityAlias().equals(meAlias) || modelViewLink.getRelEntityAlias().equals(meAlias)) {
Iterator<ModelKeyMap> kmIter = modelViewLink.getKeyMapsIterator();
while (kmIter != null && kmIter.hasNext()) {
ModelKeyMap keyMap = kmIter.next();
String fieldName = "";
if (modelViewLink.getEntityAlias().equals(meAlias)) {
fieldName = keyMap.getFieldName();
} else {
fieldName = keyMap.getRelFieldName();
}
if (Debug.verboseOn())
Debug.logVerbose("[singleUpdateView]: --- Found field to set: " + meAlias + "." + fieldName, module);
Object value = null;
if (modelViewEntity.isField(keyMap.getFieldName())) {
value = entity.get(keyMap.getFieldName());
if (Debug.verboseOn())
Debug.logVerbose("[singleUpdateView]: --- Found map value: " + value.toString(), module);
} else if (modelViewEntity.isField(keyMap.getRelFieldName())) {
value = entity.get(keyMap.getRelFieldName());
if (Debug.verboseOn())
Debug.logVerbose("[singleUpdateView]: --- Found map value: " + value.toString(), module);
} else {
throw new GenericNotImplementedException("Update on view entities: no direct link found, unable to update");
}
findByMap.put(fieldName, value);
}
}
}
// Look what there already is in the database
List<GenericValue> meResult = null;
try {
meResult = EntityQuery.use(delegator).from(meName).where(findByMap).queryList();
} catch (GenericEntityException e) {
throw new GenericEntityException("Error while retrieving partial results for entity member: " + meName, e);
}
if (Debug.verboseOn())
Debug.logVerbose("[singleUpdateView]: --- Found " + meResult.size() + " results for entity member " + meName, module);
// Got results 0 -> INSERT, 1 -> UPDATE, >1 -> View is nor updatable
GenericValue meGenericValue = null;
if (meResult.size() == 0) {
// Create new value to insert
try {
// Create new value to store
meGenericValue = delegator.makeValue(meName, findByMap);
} catch (Exception e) {
throw new GenericEntityException("Could not create new value for member entity" + meName + " of view " + modelViewEntity.getEntityName(), e);
}
} else if (meResult.size() == 1) {
// Update existing value
meGenericValue = meResult.iterator().next();
} else {
throw new GenericEntityException("Found more than one result for member entity " + meName + " in view " + modelViewEntity.getEntityName() + " - this is no updatable view");
}
// Construct fieldsToSave list for this member entity
List<ModelField> meFieldsToSave = new LinkedList<ModelField>();
for (ModelField modelField : fieldsToSave) {
if (memberModelEntity.isField(modelField.getName())) {
ModelField meModelField = memberModelEntity.getField(modelField.getName());
if (meModelField != null) {
meGenericValue.set(meModelField.getName(), entity.get(modelField.getName()));
meFieldsToSave.add(meModelField);
if (Debug.verboseOn())
Debug.logVerbose("[singleUpdateView]: --- Added field to save: " + meModelField.getName() + " with value " + meGenericValue.get(meModelField.getName()), module);
} else {
throw new GenericEntityException("Could not get field " + modelField.getName() + " from model entity " + memberModelEntity.getEntityName());
}
}
}
/*
* Finally, do the insert/update
* TODO:
* Do the real inserts/updates outside the memberEntity-loop,
* only if all of the found member entities are updatable.
* This avoids partial creation of member entities, which would mean data inconsistency:
* If not all member entities can be updated, then none should be updated
*/
if (meResult.size() == 0) {
retVal += singleInsert(meGenericValue, memberModelEntity, memberModelEntity.getFieldsUnmodifiable(), sqlP);
} else {
if (meFieldsToSave.size() > 0) {
retVal += singleUpdate(meGenericValue, memberModelEntity, meFieldsToSave, sqlP);
} else {
if (Debug.verboseOn())
Debug.logVerbose("[singleUpdateView]: No update on member entity " + memberModelEntity.getEntityName() + " needed", module);
}
}
}
return retVal;
}
Aggregations