When I add a Product with Price Lists to Work Order, it doesn't setup Unit Amount price to work order product automatically.
Manual Input is OK. But it isn't cool.
How can I do to setup Unit Amount price to work order product automatically?
and FYI, the code above is not microsoft's, I developed it. I was just another one of the outside developers who ran into this problem and needed a quick solution.
if you're still on 7.x, using resco mobile i have a woodford rule that will work.
you can take the below xml, save it as woodford-rule.xml, then import it into your work order product form. This overwrites the on change event for work order product ..so be careful with it.
<?xml version="1.0"?>
<Workflow e="true" isvalid="true" syntaxVersion="11" version="0">
<branch e="true" info="Hide Quantity and Quantity to Bill fields, along with Pricing tab, if Line Status is Estimated">
<if e="false">
<conditions e="false" op="And">
<condition e="false">
<var>ChangedItem</var>
<op>Equal</op>
<arg>String:msdyn_linestatus</arg>
</condition>
<condition e="false">
<var>Entity.msdyn_linestatus</var>
<op>Equal</op>
<arg>Picklist:690970000</arg>
</condition>
</conditions>
<action>
<function e="false">
<var>Form.msdyn_quantity.IsVisible</var>
<func>Assign</func>
<arg>Boolean:False</arg>
</function>
<function e="false">
<var>Form.msdyn_qtytobill.IsVisible</var>
<func>Assign</func>
<arg>Boolean:False</arg>
</function>
<function e="false">
<var>Tabs.Pricing.IsVisible</var>
<func>Assign</func>
<arg>Boolean:False</arg>
</function>
</action>
</if>
<if e="false">
<conditions e="false" op="And">
<condition e="false">
<var>ChangedItem</var>
<op>Equal</op>
<arg>String:msdyn_linestatus</arg>
</condition>
<condition e="false">
<var>Entity.msdyn_linestatus</var>
<op>NotEqual</op>
<arg>Picklist:690970000</arg>
</condition>
</conditions>
<action>
<function e="false">
<var>Form.msdyn_quantity.IsVisible</var>
<func>Assign</func>
<arg>Boolean:True</arg>
</function>
<function e="false">
<var>Form.msdyn_qtytobill.IsVisible</var>
<func>Assign</func>
<arg>Boolean:True</arg>
</function>
<function e="false">
<var>Tabs.Pricing.IsVisible</var>
<func>Assign</func>
<arg>Boolean:True</arg>
</function>
</action>
</if>
</branch>
<branch e="true" info="get pricing">
<if e="true">
<conditions e="true" op="And">
<condition e="false">
<var>ChangedItem</var>
<op>Equal</op>
<arg>String:msdyn_product</arg>
</condition>
<condition e="false">
<var>Entity.msdyn_product</var>
<op>ContainsData</op>
</condition>
<condition e="false">
<var>Entity.msdyn_pricelist</var>
<op>ContainsData</op>
</condition>
</conditions>
<action>
<definition e="false">
<var>varProductPriceLevel</var>
<func>LoadFetch</func>
<type>Entity</type>
<arg>String:productpricelevel</arg>
<arg>Fetch:<fetch version="1.0"><entity name="productpricelevel"><filter type="and"><condition attribute="pricelevelid" operator="eq" value="{{Entity.msdyn_pricelist}}"/><condition attribute="productid" operator="eq" value="{{Entity.msdyn_product}}"/></filter></entity></fetch></arg>
</definition>
<branch e="true" info="if pricing exists">
<if e="true">
<conditions e="true" op="And">
<condition e="false">
<var>varProductPriceLevel.@this</var>
<op>ContainsData</op>
</condition>
</conditions>
<action>
<function e="false">
<var>Entity.msdyn_estimateunitamount</var>
<func>Assign</func>
<arg>var:varProductPriceLevel.amount</arg>
</function>
</action>
</if>
</branch>
</action>
</if>
</branch>
</Workflow>
Thank you, thought this might be the case and grateful for the heads up regarding version.
We went to FS 8.8 in December, by then it hadn't been fixed either.
The JS that was included was for FS 8.8, please be aware of this if you are still on 7.x, it will not work.
Did anyone ever find out when this is due to be fixed? Is the only current solution to replace the js?
Kind regards
Will
Put the code below in an empty txt-File and save it as "WorkOrderHelper.js".
Than open your customization Mobile Project in Woodford (typically a derive of that one provided by Microsoft).
Go to Offline HTML=>Open folder "WorkOrder".
There you'll find a "WorkOrderHelper.js". Replace (overwrite) this with the new one.
If having trouble to overwrite/delete the old version (locked file), try to edit it slightly and than overwrite it afterwards.
Here is the script:
var FS = FS || {};
FS.WorkOrderHelper = {
// Sets the Work Order Product or Service's fields onLoad
setLoadValues: function (entityForm, schemaName) {
if (entityForm && entityForm.entity && entityForm.entity.properties) {
var entityProperties = entityForm.entity.properties;
if (entityProperties[schemaName.properties.msdyn_priceList] == null) {
FS.WorkOrderHelper.setDefaultValuesFromWorkOrder(entityForm.entity, schemaName);
}
if (entityProperties[schemaName.properties.msdyn_workOrderIncident] == null) {
FS.WorkOrderHelper.setWorkOrderIncident(entityForm.entity, schemaName);
}
if (entityProperties[schemaName.properties.msdyn_customerAsset] == null) {
FS.WorkOrderHelper.setCustomerAsset(entityForm.entity, schemaName);
}
if (entityForm.entity.entityName === FS.Schema.WorkOrderProduct.name) {
if (entityForm.entity.isNew && entityProperties[FS.Schema.WorkOrderProduct.properties.msdyn_warehouse] == null) {
FS.WorkOrderProduct.setWarehouse(entityForm.entity);
}
}
}
},
// Sets the Work Order Product or Service's Discount Amount, Discount Percent, Quantity, and Unit Amount fields when the Line Status changed from Estimated to Used
checkEstimateToUsedChanged: function (entity, schemaName, initial) {
if (entity && entity.properties) {
var used, estimated;
if (entity.entityName === FS.Schema.WorkOrderProduct.name) {
used = FS.Enums.msdyn_workorderproductmsdyn_LineStatus.Used;
estimated = FS.Enums.msdyn_workorderproductmsdyn_LineStatus.Estimated;
}
else if (entity.entityName === FS.Schema.WorkOrderService.name) {
used = FS.Enums.msdyn_workorderservicemsdyn_LineStatus.Used;
estimated = FS.Enums.msdyn_workorderservicemsdyn_LineStatus.Estimated;
}
var lineStatus = entity.properties[schemaName.properties.msdyn_lineStatus];
if (!entity.isNew && lineStatus === used && initial === estimated) {
if (entity.entityName === FS.Schema.WorkOrderProduct.name) {
FS.WorkOrderHelper.copyAndNullifyIfNeeded(entity, [{ pricingAttribute: FS.Schema.WorkOrderProduct.properties.msdyn_quantity, estimateAttribute: FS.Schema.WorkOrderProduct.properties.msdyn_estimateQuantity }]);
}
else if (entity.entityName === FS.Schema.WorkOrderService.name) {
FS.WorkOrderHelper.copyAndNullifyIfNeeded(entity, [{ pricingAttribute: FS.Schema.WorkOrderService.properties.msdyn_duration, estimateAttribute: FS.Schema.WorkOrderService.properties.msdyn_estimateDuration }]);
}
FS.WorkOrderHelper.copyAndNullifyIfNeeded(entity, [
{ pricingAttribute: schemaName.properties.msdyn_discountAmount, estimateAttribute: schemaName.properties.msdyn_estimateDiscountAmount },
{ pricingAttribute: schemaName.properties.msdyn_discountPercent, estimateAttribute: schemaName.properties.msdyn_estimateDiscountPercent },
{ pricingAttribute: schemaName.properties.msdyn_unitAmount, estimateAttribute: schemaName.properties.msdyn_estimateUnitAmount },
{ pricingAttribute: schemaName.properties.msdyn_unitCost, estimateAttribute: schemaName.properties.msdyn_estimateUnitCost }
]);
}
}
},
copyAndNullifyIfNeeded: function (entity, pairs) {
for (var i = 0; i < pairs.length; i++) {
entity.properties[pairs[i].pricingAttribute] = entity.properties[pairs[i].estimateAttribute] || null;
}
},
// Clears the values in the Pricing tab if Line Status is Estimated
clearPricingTab: function (entity, schemaName) {
if (entity && entity.properties) {
var lineStatus = entity.properties[schemaName.properties.msdyn_lineStatus];
var estimated;
if (entity.entityName === FS.Schema.WorkOrderProduct.name) {
estimated = FS.Enums.msdyn_workorderproductmsdyn_LineStatus.Estimated;
}
else if (entity.entityName === FS.Schema.WorkOrderService.name) {
estimated = FS.Enums.msdyn_workorderservicemsdyn_LineStatus.Estimated;
}
if (lineStatus === estimated) {
if (entity.entityName === FS.Schema.WorkOrderProduct.name) {
entity.properties[schemaName.properties.msdyn_quantity] = null;
entity.properties[schemaName.properties.msdyn_qtyToBill] = null;
}
else if (entity.entityName === FS.Schema.WorkOrderService.name) {
entity.properties[schemaName.properties.msdyn_minimumChargeAmount] = null;
entity.properties[schemaName.properties.msdyn_minimumChargeDuration] = null;
}
entity.properties[schemaName.properties.msdyn_unitAmount] = null;
entity.properties[schemaName.properties.msdyn_subtotal] = null;
entity.properties[schemaName.properties.msdyn_discountPercent] = null;
entity.properties[schemaName.properties.msdyn_discountAmount] = null;
entity.properties[schemaName.properties.msdyn_totalAmount] = null;
entity.properties[schemaName.properties.msdyn_unitCost] = null;
entity.properties[schemaName.properties.msdyn_additionalCost] = null;
entity.properties[schemaName.properties.msdyn_commissionCosts] = null;
entity.properties[schemaName.properties.msdyn_totalCost] = null;
}
}
},
// Sets the Work Order Product or Service's Description, Taxable, Name, and Unit fields
setDefaultValuesFromProduct: function (entity, schemaName, value) {
if (entity && entity.properties) {
var entityField = entity.properties[value];
if (entityField) {
var fetchEntity = new MobileCRM.FetchXml.Entity(FS.Schema.Product.name);
fetchEntity.addAttribute(FS.Schema.Product.properties.description); // index 0
fetchEntity.addAttribute(FS.Schema.Product.properties.msdyn_taxable); // index 1
fetchEntity.addAttribute(FS.Schema.Product.properties.name); // index 2
fetchEntity.addAttribute(FS.Schema.Product.properties.defaultUoMId); // index 3
fetchEntity.filter = new MobileCRM.FetchXml.Filter();
fetchEntity.filter.where(FS.Schema.Product.properties.productId, "eq", entityField.id);
var fetch = new MobileCRM.FetchXml.Fetch(fetchEntity);
fetch.execute("Array",
function (results) {
if (results && results.length > 0) {
var fetchedProduct = results[0];
if (fetchedProduct) {
MobileCRM.UI.EntityForm.requestObject(function (entityForm) {
entityForm.entity.properties[schemaName.properties.msdyn_description] = fetchedProduct[0];
entityForm.entity.properties[schemaName.properties.msdyn_taxable] = fetchedProduct[1] == "True";
entityForm.entity.properties[schemaName.properties.msdyn_name] = fetchedProduct[2];
entityForm.entity.properties[schemaName.properties.msdyn_unit] = fetchedProduct[3];
}, MobileCRM.bridge.alert);
}
}
}, MobileCRM.bridge.alert, null);
}
}
},
// Sets the Work Order Product's Price List and Currency fields
setDefaultValuesFromWorkOrder: function (entity, schemaName) {
if (entity && entity.properties) {
var workOrder = entity.properties[schemaName.properties.msdyn_workOrder];
if (workOrder) {
var fetchEntity = new MobileCRM.FetchXml.Entity(FS.Schema.WorkOrder.name);
fetchEntity.addAttribute(FS.Schema.WorkOrder.properties.msdyn_priceList); // index 0
fetchEntity.addAttribute(FS.Schema.WorkOrder.properties.transactionCurrencyId); // index 1
fetchEntity.filter = new MobileCRM.FetchXml.Filter();
fetchEntity.filter.where(FS.Schema.WorkOrder.properties.woNumber, "eq", workOrder.id);
var fetch = new MobileCRM.FetchXml.Fetch(fetchEntity);
fetch.execute("Array",
function (results) {
if (results && results.length > 0) {
var fetchedWorkOrder = results[0];
if (fetchedWorkOrder) {
MobileCRM.UI.EntityForm.requestObject(function (entityForm) {
entityForm.entity.properties[schemaName.properties.msdyn_priceList] = fetchedWorkOrder[0];
entityForm.entity.properties[schemaName.properties.transactionCurrencyId] = fetchedWorkOrder[1];
}, MobileCRM.bridge.alert);
}
}
}, MobileCRM.bridge.alert, null);
}
}
},
// Sets the Work Order Product or Service's Customer Asset field
setCustomerAsset: function (entity, schemaName) {
if (entity && entity.properties) {
var customerAsset = entity.properties[schemaName.properties.msdyn_customerAsset];
//Only Set if current CustomerAsset has not been set
if (customerAsset == null) {
var workOrderIncident = entity.properties[schemaName.properties.msdyn_workOrderIncident];
// Set the CustomerAsset of WorkOrderIncident that is on this Work Order Product or Service
if (workOrderIncident) {
FS.WorkOrderHelper.fetchWorkOrderIncidents(workOrderIncident.id, [FS.Schema.WorkOrderIncident.properties.msdyn_customerAsset], FS.Schema.WorkOrderIncident.properties.msdyn_workOrderIncidentId,
function (results) {
if (results && results.length > 0) {
var fetchedWOIncident = results[0];
if (fetchedWOIncident) {
MobileCRM.UI.EntityForm.requestObject(function (entityForm) {
entityForm.entity.properties[schemaName.properties.msdyn_customerAsset] = fetchedWOIncident[0];
}, MobileCRM.bridge.alert);
}
}
}, MobileCRM.bridge.alert, null);
}
else { //Set the CustomerAsset of the first (non-primary) WorkOrderIncident from the same WorkOrder that is on this Work Order Product or Service
var workOrder = entity.properties[schemaName.properties.msdyn_workOrder];
if (workOrder) {
FS.WorkOrderHelper.fetchWorkOrderIncidents(workOrder.id, [FS.Schema.WorkOrderIncident.properties.msdyn_customerAsset], FS.Schema.WorkOrderIncident.properties.msdyn_workOrder,
function (results) {
if (results && results.length > 0) {
var fetchedWOIncident = results[0];
if (fetchedWOIncident && fetchedWOIncident[0]) {
MobileCRM.UI.EntityForm.requestObject(function (entityForm) {
entityForm.entity.properties[schemaName.properties.msdyn_customerAsset] = fetchedWOIncident[0];
}, MobileCRM.bridge.alert);
}
}
}, MobileCRM.bridge.alert, null);
}
}
}
}
},
// Sets the Work Order Product or Service's Work Order Incident field
setWorkOrderIncident: function (entity, schemaName) {
if (entity && entity.properties) {
var workOrder = entity.properties[schemaName.properties.msdyn_workOrder];
if (workOrder) {
FS.WorkOrderHelper.fetchWorkOrderIncidents(workOrder.id, [FS.Schema.WorkOrderIncident.properties.msdyn_workOrderIncidentId, FS.Schema.WorkOrderIncident.properties.msdyn_name], FS.Schema.WorkOrderIncident.properties.msdyn_workOrder,
function (results) {
if (results && results.length === 1) {
//results[0][0] is the msdyn_workOrderIncidentId field and results[0][1] is the msdyn_name field
var workOrderIncidentReference = new MobileCRM.Reference(FS.Schema.WorkOrderIncident.name, results[0][0], results[0][1]);
MobileCRM.UI.EntityForm.requestObject(function (entityForm) {
entityForm.entity.properties[schemaName.properties.msdyn_workOrderIncident] = workOrderIncidentReference;
}, MobileCRM.bridge.alert);
}
}, MobileCRM.bridge.alert, null);
}
}
},
fetchWorkOrderIncidents: function (id, attributes, fetchType, success, failure, scope) {
var fetchEntity = new MobileCRM.FetchXml.Entity(FS.Schema.WorkOrderIncident.name);
for (var i = 0; i < attributes.length; i++) {
fetchEntity.addAttribute(attributes[i]);
}
fetchEntity.filter = new MobileCRM.FetchXml.Filter();
fetchEntity.filter.where(fetchType, "eq", id);
var fetch = new MobileCRM.FetchXml.Fetch(fetchEntity);
fetch.execute("Array", success, failure, scope);
}
};
Sure, can send you the script. Let me just find out again, how the deployment needs to be done. There was a trick for it.
Moko,
we are having issues with this as well. i found out that clearing the $0.00 in the unit amount and then saving does populate the price as well.
Can you email me or get me a copy of the .js that Microsoft gave you for a fix?
Hello Alexander and Ryota. I just had an extensive session with a Field Service Mobile Engineer from Microsoft US. He provided me with a JS script that fixes the issue reported by Ryota. He said it would be officially released by MS in a future update of the Mobile Project.
Thank you for answering.
I asked a question because the functions that can be realized in FS can not be realized in FS mobile.
>I have reached out to the PM to see if we can update the documentation.
It would be helpful if you could mention the differences between FS and FS mobile in Microsoft Docs.
Stay up to date on forum activity by subscribing. You can also customize your in-app and email Notification settings across all subscriptions.
André Arnaud de Cal... 290,818 Super User 2024 Season 2
Martin Dráb 229,147 Most Valuable Professional
nmaenpaa 101,156