# Everpro Tracking and Callback External Order
## Via NSQ
```plantuml
participant "another service" as a
participant "everpro-3pl-aggregator" as 3plagg
participant "NSQ" as nsq
participant "everpro-order" as eo
database "popaket_order" as db
participant "everpro-client-gateway" as ecg
database "popaket_user_logistic" as db2
participant "3PL" as 3pl
actor "user-external" as user
== produce order data ==
a -> 3plagg : create order via grpc
activate 3plagg
3plagg -> 3pl : create order to 3pl
3pl -> 3plagg : return AWB number
3plagg -> nsq : publish data to topic `create-order-data`
3plagg -> a : return AWB number
deactivate 3plagg
== consume order data ==
nsq -> eo : consume from topic `create-order-data`
activate eo
alt if shipment order number not found
eo -> eo : set error to nil to avoid requeued to NSQ
end
eo -> db : update awb
db --> eo
alt if 3pl does not have webhook
eo -> nsq : publish tracking data to topic `tracking-order-status`
end
deactivate eo
== tracking ==
nsq -> eo : consume tracking data from topic `tracking-order-status`
activate eo
eo -> db : get order data
db --> eo : return order data
eo -> 3plagg : tracking order
3plagg -> eo : return the tracking history
alt if tracking code == "CREATED"
eo -> nsq : publish data to topic `shipment-callback-url`
else if tracking code == "PICKEDUP"
eo -> db : update order status
eo -> nsq : re-publish back to topic `tracking-order-status`
eo -> nsq : publish data to topic `shipment-callback-url`
else if tracking code == "DELIVERED"
eo -> db : update order status
eo -> nsq : publish data to topic `shipment-callback-url`
else if tracking code == "RETURNED"
eo -> db : update order status
eo -> nsq : publish data to topic `shipment-callback-url`
else if tracking code == "CANCELED"
eo -> db : update order status
eo -> nsq : publish data to topic `shipment-callback-url`
end
== Sending Callback to Client ==
nsq -> ecg : consume from topic `shipment-callback-url`
activate ecg
ecg -> db2 : get user callback url
db2 --> ecg
ecg -> user : send updated tracking code to client via callback url
user -> ecg : return response
alt if response is error
ecg -> nsq : re-publish to NSQ to be retried later
end
deactivate ecg
```
## Via Cron
```plantuml
participant "Cron" as cron
participant "everpro-logistic-client" as elc
database "popaket_order" as db
participant "NSQ" as nsq
participant "everpro-order" as eo
participant "everpro-logistic" as el
database "popaket_user_logistic" as db2
database "redis" as redis
== Get Uncompleted Order ==
cron -> elc : hit endpoint `/v1/public/shipment/bulk-tracking-external`
activate elc
alt if offset < total data
elc -> db : get uncompleted order external
db --> elc : return orders
group loop the orders
elc -> nsq : publish the order to topic `bulk-tracking-external`
end
elc -> elc : back to get uncompleted order external
end
elc -> cron : return success
deactivate elc
== Track The Order ==
nsq -> elc : consume from topic `bulk-tracking-external`
activate elc
alt is using new tracking ?
elc -> eo : get tracking
else
elc -> el : track the AWB
elc -> db2 : get the user callback data
db2 --> elc
elc -> redis : set the callback data
end
elc -> db : update order status
elc -> redis : save tracking data
deactivate elc
== Sending Callback to Clien ==
cron -> elc : hit endpoint `/v1/public/shipment/tracking-external-callback`
activate elc
elc -> redis : get tracking data from redis
group loop the tracking data
elc -> redis : get user callback data
elc -> elc : convert last order status id to tracking code
elc -> user : send request to callback url
user -> elc : return response
alt if response status != 200
elc -> redis : save tracking data back to redis
else
elc -> redis : delete the tracking data
end
end
elc -> cron : return success
deactivate elc
```