# Everpro Invoice
## Main Flow
```graphviz
digraph G {
rankdir="LR";
"appsmith / cron" -> "everpro-invoice" -> "everdoc (pdf generator)"
}
```
## Order List AppSmith
```plantuml
participant appsmith as as
participant "everpro-invoice" as ep
database "everpro_invoice" as db
participant "everpro-logistic-client" as elc
participant "everpro-order" as eo
as -> ep : getting order list based on filter
activate ep
group get the internal order list
ep -> elc : get the internal order list via grpc
activate elc
elc -> ep : return the order list
deactivate elc
end group
group get the external order list
ep -> eo : get the external order list via grpc
activate eo
eo -> ep : return the order list
deactivate eo
end group
ep -> db : get the invoice pdf link based on shipment order number
db -> ep : return the pdf link
ep -> ep : combine the order link with pdf link
ep -> as : return order list + pdf link
deactivate ep
```
## Generate Invoice
### Single generate
#### Tracking
```plantuml
actor user as u
participant "everpro-logistic-client" as elc
database "popaket_logistic" as db
participant "everpro-3pl-aggregator" as 3plagg
participant "3PL" as 3pl
participant "NSQ" as nsq
u -> elc : hit tracking button
activate elc
elc -> 3plagg : request tracking
activate 3plagg
3plagg -> 3pl : get tracking data from 3PL
3pl -> 3plagg : return the tracking data
3plagg -> 3plagg : map the tracking status with our order status
3plagg -> elc : return the tracking history with order status
deactivate 3plagg
elc -> db : update the order status
group produce the data that needed to generate the invoice
elc -> nsq : publish the invoice data to NSQ topic
end group
elc -> u : return the tracking history
deactivate elc
```
#### Invoice
```plantuml
participant "NSQ" as nsq
participant "everpro-invoice" as ep
participant "everdoc" as pdf
database "everpro_invoice" as db
nsq -> ep : consume the invoice data from NSQ
activate ep
ep -> ep : prepare the request body for generate a pdf
ep -> pdf : send a request to generate pdf link
pdf -> ep : return a pdf link or error
alt if the generate process return an error, publish back to NSQ to be retried later
ep -> nsq : produce the data that needed to generate the invoice
end alt
ep -> db : save the link
deactivate ep
```
### Bulk generate via cron
```plantuml
participant cron as cron
participant "everpro-invoice" as ei
database "redis" as redis
database "everpro_invoice" as db
participant "everpro-logistic-client" as elc
participant "everpro-order" as eo
participant "everdoc" as pdf
cron -> ei : bulk generate via cron
activate ei
ei -> ei : getting the order for internal and external in paralel
group get the internal order list using pagination
ei -> redis : get the pagination
redis --> ei
ei -> elc : get the internal order list via grpc
activate elc
elc -> ei : return the order list
deactivate elc
ei -> redis : set the current pagination to redis
note left
When the next cycle running,
we continue the pagination.
So we dont need to start from beginning.
end note
end group
group get the external order list using pagination
ei -> redis : get the pagination
redis --> ei
ei -> eo : get the external order list via grpc
activate eo
eo -> ei : return the order list
deactivate eo
ei -> redis : set the current pagination to redis
note left
When the next cycle running,
we continue the pagination.
So we dont need to start from beginning.
end note
end group
ei -> ei : combine the order list to 1 array
group loop the orders
ei -> db : check the is the order has a pdf link
db --> ei
alt if the pdf link not found, generate the pdf
ei -> pdf : generate the pdf
pdf -> ei : return the pdf link
ei -> db : save the pdf link
else if already have a pdf link, skip it
ei -> ei : skip the order
end
end group
ei -> cron : return success
deactivate ei
```
## Download pdf as zip
```plantuml
participant appsmith as as
participant "everpro-invoice" as ei
database "everpro_invoice" as db
participant "everdoc" as pdf
participant "AWS S3" as s3
as -> ei : send a list of shipment order number
activate ei
group loop the shipment order number
ei -> db : check is pdf link available
db -> ei : get the pdf link
ei -> pdf : open the pdf link
activate pdf
pdf -> s3 : get the public link
s3 --> pdf
pdf -> ei : redirect to public link, pdf downloaded
deactivate pdf
ei -> ei : collect the pdf
end group
ei -> ei : generating a zip file to download
ei -> as : send a zip link to download
deactivate ei
```
## Download pdf as zip v2
```plantuml
participant appsmith as as
participant "everpro-invoice" as ei
participant "everpro-logistic-client" as elc
database "everpro_invoice" as db
participant "everdoc" as pdf
as -> ei : download zip request
alt if reference number > 0
ei -> db : get invoice data from `invoices` table
db --> ei
group loop the invoice data
ei -> pdf : hit the pdf link to download the file
pdf -> ei : return the pdf file
ei -> ei : add file to zip
end
else if no reference number
ei -> elc : get the internal orders via grpc
elc -> ei : return the order list
alt if the orders length is more than 0
group loop the orders
ei -> db : get the invoice data
db --> ei
ei -> pdf : hit the pdf link to download the file
pdf -> ei : return the pdf file
ei -> ei : add file to zip
end
ei -> ei : recursive back to get interal order again
end
end
ei -> as : return the zip file
```