---
# System prepended metadata

title: Everpro Generate AWB

---

# 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
```