# Everpro Generate AWB
## Bulk Create Order (internal CMS)
```plantuml
participant "frontend" as fe
participant "everpro-logistic-client" as elc
participant "NSQ" as nsq
database "popaket_logistic" as db
participant "everpro-3pl-aggregator" as 3plagg
participant "everpro-logistic-openapi" as elo
participant "everpro-wallet" as wallet
fe -> elc : create bulk upload order
activate elc
elc -> elc : existing create order logic \n(check is eligible, \nget popcash balance,\nCOD KYC checking,\nisaccount suspended)
group looping orders
elc -> elc : spawn goroutine
elc -> db : get setting from db(insurance setting,\nshipment setting,etc)
note right
we can improve this, by moving the setting data to redis
end note
elc -> 3plagg : get weight rounding setting
note right
heads up !!!
at this point, we rely on 3pl-aggregator
we must handle if we cannot hit 3pl-aggregator
end note
3plagg --> elc
elc -> elc : another logic process\n(get location by postal code or subdistrict name)
elc -> elo : get rate (with redis cache)
elo --> elc
elc -> elc : another logic process (rts scoring, etc)
end
elc -> elc : goroutine wait
group looping orders
elc -> elc : spawn goroutine
elc -> elc : calculate ERP
end
elc -> elc : goroutine wait
elc -> db : save to database using trx
elc -> elc : spawn 3 goroutines
group goroutine 1 (payment and generate awb)
elc -> nsq : publish to nsq topic "payment"
alt if there are cod order (calling BulkUpdatePaymentStatus func)
group loop cod orders
group spawn goroutine
elc -> db : get order data
db --> elc
elc -> db : activate or deactivate order
group spawn 1 goroutine
elc -> db : getting 3pl and origin data
elc -> elc : sending to slack
end
note right
I think we can remove this block, because its useless
end note
elc -> elc : spawn 2 goroutines
group goroutine 1 (generate awb)
elc -> elc : calling function autoGenerateAwb()
note right
the autoGenerateAwb() process will be breakdown to separate diagram
endnote
end
group goroutine 2 (generate awb)
elc -> nsq : publish to topic "update-status-paid"
end
elc -> nsq : generate invoice for order non cod
end
end
elc -> elc : waiting goroutine
end
end
group goroutine 2 (create order history)
elc -> nsq : publish to topic "create-order-history"
end
group goroutine 3 (popcash)
group loop orders
alt if order is COD
elc -> nsq : publish to topic "popcash-insert"
end
alt if order has cashback and COD
elc -> wallet : insert credit note
end
end
end
elc -> elc : waiting goroutine
elc -> fe : return success
deactivate elc
```
### autoGenerateAwb()
```plantuml
participant "everpro-logistic-client" as elc
participant "NSQ" as nsq
database "popaket_logistic" as db
participant "everpro-logistic" as el
participant "everpro-3pl-aggregator" as 3plagg
participant "everpro-wallet" as wallet
elc -> db : insert to auto_generate_awbs table
elc -> elc : check need to delay generate awb or not
loop 5 times
elc -> db : get data from table auto_generate_awbs
elc -> elc : increase retry count
elc -> db : update retry
== start generating AWB ==
elc -> elc : calling GenerateAWB() func
elc -> db : get order
elc -> elc : return error if order already canceled
elc -> db : get data for awb request (join : shipment_orders,logistics,logistic_rates,package_types)
alt if logistic is not JNT
elc -> db : get origin code from logistic_codes
db --> elc
elc -> db : get destination code from logistic_codes
db --> elc
end
elc -> elc : set the pickup time
alt if awb generated from 3pl-aggregator
elc -> 3plagg : generate AWB via grpc
3plagg --> elc : response
else
elc -> el : generate AWB via http
el --> elc : response
end
alt if AWB response is not empty
elc -> db : update AWB number
alt if order is non cod and have cashback
elc -> wallet : insert credit note
end
end
elc -> nsq : publish to nsq topic "update-awb-order-history"
== end generate AWB ==
alt if generate awb return err
elc -> elc : break loop if order already has awb
elc -> elc : break loop if order already canceled
alt if already retry 5 times
elc -> db : update order status to 202 (shipment_orders table)
end
elc -> elc : sleep 30 minutes
elc -> elc : back to loop
end
elc -> db : delete from auto_generate_awbs
end
```