Authors:
Valery Kornilovich, Randy Chan
Changed on:
4 July 2024
As a Store associate, I would like to take a photo of the returned item during the return in-store process.
As a Return Storeman in the warehouse, I would like to take a photo of the returned item during the return process.
To support the business solution design, the following technical areas need to be enhanced:
`ReturnItemsExtended`
`CreateReturnOrderFromOrder`
`RETURN_IMAGE_OPTIONS`
For training purposes, the camera package can be downloaded here: https://www.npmjs.com/package/react-html5-camera-photo
Create a new file:
`PhotoCapture.tsx.`
This class will provide the PhotoCapture button function.
1 const showModal = (imageUri?: string) => {
2 pushModal({
3 title: translate(
4 'fc.sf.ui.returns.orders.createReturnOrder.list.returnItem.takePicture',
5 ),
6 body: (
7 <div style={{ padding: '20px' }}>
8 {imageUri ? (
9 <img src={imageUri} alt="" className={classes.returnPopupImg} />
10 ) : (
11 <Camera
12 onTakePhotoAnimationDone={handleTakePhotoAnimationDone}
13 onCameraError={() => {
14 setDataUri('');
15 }}
16 idealResolution={{
17 width: 640,
18 height: 480,
19 }}
20 imageType={imageType}
21 imageCompression={+imageCompression}
22 isDisplayStartCameraError={true}
23 />
24 )}
25
26 {imageUri && (
27 <div className={classes.returnPopupBtns}>
28 <Button
29 onClick={() => {
30 updateDataUri();
31 }}
32 variant="contained"
33 color="primary"
34 >
35 {translate(
36 'fc.sf.ui.returns.orders.createReturnOrder.list.returnItem.retake',
37 )}
38 </Button>
39 <Button onClick={clearModals} variant="contained" color="primary">
40 {translate(
41 'fc.sf.ui.returns.orders.createReturnOrder.list.returnItem.ok',
42 )}
43 </Button>
44 </div>
45 )}
46 </div>
47 ),
48 });
49 };
Language: tsx
Name: PhotoCapture.tsx showModal snippet
Description:
PhotoCapture.tsx showModal snippet
1 return (
2 <>
3 <>
4 <IconButton
5 onClick={() => {
6 showModal(dataUri);
7 }}
8 >
9 <AddAPhoto />
10 </IconButton>
11
12 {dataUri && <img src={dataUri} alt="" className={classes.returnImg} />}
13 </>
14 </>
15 );
Language: tsx
Name: PhotoCapture.tsx return snippet
Description:
PhotoCapture.tsx return snippet
Next, add PhotoCapture details into ReturnItemsExtended.tsx
1//when there is an update, add the details into the item attribute
2 if (returnItem.photo && selectedReturnItem) {
3 selectedReturnItem.attributes = [ { name: 'returnImage', value: returnItem.photo, type: 'STRING', }, ];
4 }
5
6
7// dcreate thshis const as part of the class,
8 const imageCaptureAttr: TranslatableAttribute = {
9 type: 'component',
10 label:
11 'i18n:fc.sf.ui.returns.orders.createReturnOrder.list.returnItem.imageCapture',
12 labelFallback: 'Capture',
13 options: {
14 component: 'fc.photo.capture',
15 props: {
16 id: '{{node.state.orderItemRef}}',
17 onChange: handleImgChange,
18 data: dataWithState?.orderById.items,
19 },
20 },
21 align: 'center',
22 };
23
24 // when there is a change:
25 const handleImgChange = (event: PhotoCaptureEvent) => {
26 const returnItem = state.returnItems.find(
27 (i) => i.orderItemRef === event.id,
28 );
29 if (!returnItem) {
30 console.error(
31 'Error handling quantity selector change: Could not find item with ref ' +
32 event.id,
33 );
34 return;
35 }
36 const returnItemUpdate = { ...returnItem };
37 returnItemUpdate.photo = event.value;
38
39 dispatch({ type: 'update', value: returnItemUpdate });
40 };
41
Language: tsx
Name: add PhotoCapture details into ReturnItemsExtended.tsx
Description:
add PhotoCapture details into ReturnItemsExtended.tsx
The new rule CreateReturnOrderFromOrder has been added to a custom rule plugin. It's an enhanced version of the basic rule from module-order. Additional code accepts new EventAttributes supported by UI changes and saves them.
Property | Value |
Plugin name | <yourPluginName> |
Rule API Client | GraphQL |
Rule Info Description | Creates a return entity to begin the process of refunding the returned items. |
Supported Entities | ORDER |
1//event attribute changes
2@EventAttribute(name = "returnItems",
3 type = "RETURN_ITEMS")
4@EventAttribute(name = "pickupLocation")
5@EventAttribute(name = "lodgedLocation")
6@EventAttribute(name = "destinationLocation")
7@EventAttribute(name = "type")
8
9//save information about lodged location if it present in "lodgedLocation" or "pickupLocation"
10 boolean hasLodgedLocation = false;
11 String lodgedLocation = null;
12
13 lodgedLocation = tryGetValueForKeyOrNull(pickupLocationMap, "lodgedLocation", "pickupLocation", String.class);
14 if (!isEmptyOrBlank(lodgedLocation)) {
15 hasLodgedLocation = true;
16 }
17
18...
19 if (!hasLodgedLocation) {
20 lodgedLocation = tryGetValueForKeyOrNull(event.getAttributes(), "lodgedLocation", "", String.class);
21 hasLodgedLocation = !isEmptyOrBlank(lodgedLocation);
22 }
23
24
25//save attributes at the end of createReturnItem
26 // append attributes
27 List attributes = tryGetValueForKeyOrNull(returnItemMap, "attributes", "", List.class);
28 if (attributes != null) {
29 List<Attribute> attributesConverted = ValueConverter.convertList(attributes, Attribute.class);
30 returnItemBuilder.attributes(attributesConverted.stream()
31 .map(a -> AttributeInput.builder().name(a.getName()).value(a.getValue()).type(a.getType()).build())
32 .collect(Collectors.toList()));
33 }
34
Language: java
Name: Example required of changes in CreateReturnOrderFromOrder
Description:
Modified CreateReturnOrderFromOrder rule
Rule CreateReturnOrderFromOrder was updated and added a new type returnItemsImage. To use it workflow has to be updated.
1{
2 "name": "ReturnOrder",
3 "description": "This ruleset is triggered when an event has been sent to initiate a Return against an Order. ",
4 "type": "ORDER",
5 "subtype": "HD",
6 "eventType": "NORMAL",
7 "rules": [
8 {
9 "name": "{{fluent.account.id}}.order.ValidateReturnQty",
10 "props": null
11 },
12 {
13 "name": "{{fluent.account.id}}.{packageName}.CreateReturnOrderFromOrder",
14 "props": null
15 },
16 {
17 "name": "{{fluent.account.id}}.core.SetState",
18 "props": {
19 "status": "RETURN_CREATED"
20 }
21 }
22 ],
23 "triggers": [
24 {
25 "status": "COMPLETE"
26 },
27 {
28 "status": "RETURN_CREATED"
29 },
30 {
31 "status": "RETURN_COMPLETE"
32 }
33 ],
34 "userActions": [
35 {
36 "context": [
37 {
38 "label": "Submit Return",
39 "type": "PRIMARY",
40 "modules": [
41 "adminconsole",
42 "store",
43 "servicepoint"
44 ],
45 "confirm": false
46 }
47 ],
48 "attributes": [
49 {
50 "name": "returnItems",
51 "label": "Items",
52 "type": "returnItemsImage",
53 "source": "",
54 "defaultValue": "",
55 "mandatory": true
56 },
57 {
58 "name": "pickupLocation",
59 "label": "Pickup Location",
60 "type": "ADDRESS",
61 "source": "",
62 "defaultValue": "",
63 "mandatory": false
64 },
65 {
66 "name": "lodgedLocation",
67 "label": "Lodged Location",
68 "type": "STRING",
69 "source": "",
70 "defaultValue": "",
71 "mandatory": false
72 },
73 {
74 "name": "type",
75 "label": "Return Type",
76 "type": "STRING",
77 "source": "",
78 "options": {
79 "active": [
80 {
81 "name": "Default",
82 "value": "DEFAULT"
83 }
84 ]
85 },
86 "defaultValue": "",
87 "mandatory": false
88 }
89 ]
90 }
91 ]
92 }
Language: json
Name: Home Delivery (HD)
Description:
HD workflow changes
1{
2 "name": "ReturnOrder",
3 "description": "Validate if the item can be returned and create the return order",
4 "type": "ORDER",
5 "subtype": "CC",
6 "eventType": "NORMAL",
7 "rules": [
8 {
9 "name": "{{fluent.account.id}}.order.ValidateReturnQty",
10 "props": null
11 },
12 {
13 "name": "{{fluent.account.id}}.{packageName}.CreateReturnOrderFromOrder",
14 "props": null
15 },
16 {
17 "name": "{{fluent.account.id}}.core.SetState",
18 "props": {
19 "status": "RETURN_CREATED"
20 }
21 }
22 ],
23 "triggers": [
24 {
25 "status": "COMPLETE"
26 },
27 {
28 "status": "RETURN_CREATED"
29 },
30 {
31 "status": "RETURN_COMPLETE"
32 }
33 ],
34 "userActions": [
35 {
36 "context": [
37 {
38 "label": "Submit Return",
39 "type": "PRIMARY",
40 "modules": [
41 "adminconsole",
42 "store",
43 "servicepoint"
44 ],
45 "confirm": false
46 }
47 ],
48 "attributes": [
49 {
50 "name": "returnItems",
51 "label": "Items",
52 "type": "returnItemsImage",
53 "source": "",
54 "defaultValue": "",
55 "mandatory": true
56 },
57 {
58 "name": "pickupLocation",
59 "label": "Pickup Location",
60 "type": "ADDRESS",
61 "source": "",
62 "defaultValue": "",
63 "mandatory": false
64 },
65 {
66 "name": "lodgedLocation",
67 "label": "Lodged Location",
68 "type": "STRING",
69 "source": "",
70 "defaultValue": "",
71 "mandatory": false
72 },
73 {
74 "name": "type",
75 "label": "Return Type",
76 "type": "STRING",
77 "source": "",
78 "options": {
79 "active": [
80 {
81 "name": "Default",
82 "value": "DEFAULT"
83 }
84 ]
85 },
86 "defaultValue": "",
87 "mandatory": false
88 }
89 ]
90 }
91 ]
92}
Language: json
Name: Click and Collect (CC)
Description:
CC workflow changes
1{
2 "imageType": "jpg",
3 "imageCompression": "0.3"
4}
Language: json
Name: RETURN_IMAGE_OPTIONS
Description:
Type: JSON
This setting is for image type and image compression.
imageType can contain ‘jpg’ or ‘png’ type.
imageCompression can contain a number from 0 to 1. 0 - is a maximum compression, 1 - is an original image. imageCompression works only with ‘jpg’ imageType.
The result of the return image functionality enables Store Users to capture a photo of the item being returned. This photo is then attached to the returnOrder entity, providing a visual confirmation of the item's condition at the time of return. This feature enhances the return process by adding a layer of transparency and accountability, which can be beneficial for both the customer and the business.
Copyright © 2024 Fluent Retail Pty Ltd (trading as Fluent Commerce). All rights reserved. No materials on this docs.fluentcommerce.com site may be used in any way and/or for any purpose without prior written authorisation from Fluent Commerce. Current customers and partners shall use these materials strictly in accordance with the terms and conditions of their written agreements with Fluent Commerce or its affiliates.