Hi @koaning
Here is the code,
class OrderLineAttributeForm(FormAction):
def name(self) -> Text:
return "order_lineattribute_form"
@staticmethod
def required_slots(tracker: "Tracker") -> List[Text]:
return ["orderNumber", "lineNumber"]
def slot_mappings(self):
return {"orderNumber": self.from_entity(entity="orderNumber",
intent=["orderline_details",
"inform"]),
"lineNumber": self.from_entity(entity="lineNumber",
intent=["orderline_details",
"inform"])}
@staticmethod
def validate_orderNumber(
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> Dict[Text, Any]:
token = tracker.get_slot('st_token')
ordernumber_response = order_api.get_orderheader_orderno(order_number=value,
st_token=token,
env=environment)
if ordernumber_response.status_code == 400:
* Some utterances *
return {"orderNumber": None}
return {"orderNumber": value}
async def validate_slots(
self,
slot_dict: Dict[Text, Any],
dispatcher: "CollectingDispatcher",
tracker: "Tracker",
domain: Dict[Text, Any],
) -> List[EventType]:
token = tracker.get_slot('st_token')
order_number = tracker.get_slot('orderNumber')
line_number = tracker.get_slot('lineNumber')
slot_dict.update({'orderNumber': order_number})
slot_dict.update({'lineNumber': line_number})
for slot, value in list(slot_dict.items()):
validate_func = getattr(self, f"validate_{slot}", lambda *x: {slot: value})
if utils.is_coroutine_action(validate_func):
validation_output = await validate_func(
value, dispatcher, tracker, domain
)
else:
validation_output = validate_func(value, dispatcher, tracker, domain)
if not isinstance(validation_output, dict):
validation_output = {slot: validation_output}
slot_dict.update({'is_order_validated': True})
slot_dict.update(validation_output)
if slot == 'lineNumber':
order_number = slot_dict['orderNumber']
if order_number:
output = order_search.validate_line_number(order_number=order_number,
line_number=value,
token=token,
environment=environment)
text = output['text']
if text:
dispatcher.utter_message(text)
isvalid = output['isvalid']
if not isvalid:
slot_dict[slot] = None
print("Line number invalid")
ret = [SlotSet(slot, value) for slot, value in slot_dict.items()] + [
FollowupAction('action_get_lines')]
return ret
else:
slot_dict[slot] = value
return [SlotSet(slot, value) for slot, value in slot_dict.items()]
In this the “lineNumber” validation (Inside validation_slots) depends on “orderNumber” and if “orderNumber” changes i have to validate “lineNumber” too.
For eg. If user provides wrong order number and some line number and then provides the right “orderNumber” through validation, I have to check line number again.
Another scenario, If the user provides “lineNumber” and not the “orderNumber” in the utterance which activates this form action, I could not validate “lineNumber”.
I have used validation_slots function because I have to validate prefilled slots.
I have implemented the logic where every time both the slots are validated, which for now handles my problem. But this looks messy. Please help me if there is any better way to handle this.
Another question:
If line number is invalid I have to call other action. I have used Followup Action in the validation(Please let me know whether this is right approach).
Please help @akelad
Thanks in advance