1 {-# LANGUAGE OverloadedLists #-}
3 module Literate.Organization where
5 import Country qualified
6 import Country.Identifier qualified as Country
7 import Data.Text qualified as Text
8 import Literate.Document qualified as Doc
9 import Literate.Document.HTML qualified as HTML
10 import Literate.Prelude
11 import Text.Printf qualified as Printf
12 import Prelude qualified
14 data EntityId = EntityId {unEntityId :: Natural}
15 deriving (Eq, Ord, Show)
16 instance HTML.ToMarkup EntityId where
17 toMarkup i = i & unEntityId & HTML.toHtml
18 instance Doc.ToInline EntityId where
19 toInline i = i & unEntityId & show & Doc.toInline
21 data URL = URL {unURL :: Text}
22 deriving (Eq, Ord, Show)
23 instance IsString URL where
24 fromString = URL . fromString
25 instance Doc.ToInline URL where
26 toInline = unURL >>> Doc.Target >>> Doc.inlineLinkExplicit
32 deriving (Eq, Ord, Show)
33 instance IsString Email where
35 case s & fromString & Text.split (== '@') of
36 [emailLocal, emailServer] -> Email{..}
37 _ -> Prelude.error $ "IsString Email: " <> s
38 instance Doc.ToBlock Email where
39 toBlock = Doc.toBlock . Doc.toInline
40 instance Doc.ToInline Email where
43 { Doc.inlineLinkText =
44 [ eml & emailLocal & Doc.toInline
46 , eml & emailServer & Doc.toInline
49 , Doc.inlineLinkTarget =
61 -- newtype Organization = Organization (Tree.Tree (Role, Organization))
62 -- organization = Organization (Tree.Node ("", entity) [])
66 , orgParts :: [(Role, Organization)]
68 deriving (Eq, Ord, Show)
75 { entityId :: EntityId
76 , entityAddress :: Maybe Address
77 , entityEmail :: Maybe Email
78 , entityIBAN :: Maybe IBAN
79 , entityName :: Maybe Text
80 , entityPhone :: Maybe Phone
81 , entitySIREN :: Maybe Text
83 deriving (Eq, Ord, Show)
84 instance Doc.ToBlock Entity where
91 [ [ "Name" := addr & Doc.toBlock
92 | addr <- ent & entityName & maybeToList
94 , [ "Address" := addr & Doc.toBlock
95 | addr <- ent & entityAddress & maybeToList
97 , [ "SIREN" := siren & Doc.toBlock
98 | siren <- ent & entitySIREN & maybeToList
100 , [ "Email" := email & Doc.toBlock
101 | email <- ent & entityEmail & maybeToList
103 , [ "Phone" := phone & Doc.toBlock
104 | phone <- ent & entityPhone & maybeToList
106 , [ "IBAN" := iban & Doc.toBlock
107 | iban <- ent & entityIBAN & maybeToList
111 instance Doc.ToBlock Organization where
115 [ if (org & orgEntity) == entity then Doc.emptyBlock else Doc.toBlock $ org & orgEntity
118 [ role & Doc.toInline := part & Doc.toBlock
119 | (role, part) <- org & orgParts
124 | Text.null role = "" :: Doc.Inline
126 Doc.classes @Doc.Inline ["entity-role"] $
127 "(" <> Doc.toInline role <> ")"
130 { entityId = EntityId 0
131 , entityAddress = Nothing
132 , entityEmail = Nothing
133 , entityIBAN = Nothing
134 , entityName = Nothing
135 , entityPhone = Nothing
136 , entitySIREN = Nothing
139 data Address = Address
140 { addressText :: [Text]
141 , addressZipCode :: ZipCode
142 , addressCity :: City
143 , addressCountry :: Country.Country
145 deriving (Eq, Ord, Show)
146 instance Doc.ToBlock Address where
148 Doc.classes ["address"] $
152 | t <- addr & addressText
158 $ [ addr & addressZipCode & Doc.toInline
159 , addr & addressCity & Doc.toInline
160 , addr & addressCountry & Country.encodeEnglish & Doc.toInline
166 , addressZipCode = ""
168 , addressCountry = Country.france
174 -- | International Bank Account Number
176 { ibanCountry :: Country.Country
177 , ibanCheckDigits :: Natural
178 , ibanBasicBankAccountNumber :: Text
180 deriving (Eq, Ord, Show)
182 instance Doc.ToBlock IBAN where
184 [ iban & ibanCountry & Country.alphaTwoUpper & Doc.toInline
185 , iban & ibanCheckDigits & (Printf.printf "%02d" :: _ -> String) & Doc.toInline
187 , iban & ibanBasicBankAccountNumber & Text.chunksOf 4 & Text.intercalate " " & Doc.toInline