1 {-# LANGUAGE DeriveAnyClass #-}
2 {-# LANGUAGE OverloadedLists #-}
4 module Literate.Organization where
6 import Country qualified
7 import Country.Identifier qualified as Country
8 import Data.Text qualified as Text
9 import Literate.Document qualified as Doc
10 import Literate.Document.HTML qualified as HTML
11 import Literate.Prelude
12 import Text.Printf qualified as Printf
13 import Prelude qualified
15 data EntityId = EntityId {unEntityId :: Natural}
16 deriving (Eq, Ord, Show, Generic, NFData)
17 instance HTML.ToMarkup EntityId where
18 toMarkup i = i & unEntityId & HTML.toHtml
19 instance Doc.ToInline EntityId where
20 toInline i = i & unEntityId & show & Doc.toInline
22 data URL = URL {unURL :: Text}
23 deriving (Eq, Ord, Show, Generic, NFData)
24 instance IsString URL where
25 fromString = URL . fromString
26 instance Doc.ToInline URL where
27 toInline = unURL >>> Doc.Target >>> Doc.inlineLinkExplicit
33 deriving (Eq, Ord, Show, Generic, NFData)
34 instance IsString Email where
36 case s & fromString & Text.split (== '@') of
37 [emailLocal, emailServer] -> Email{..}
38 _ -> Prelude.error $ "IsString Email: " <> s
39 instance Doc.ToBlock Email where
40 toBlock = Doc.toBlock . Doc.toInline
41 instance Doc.ToInline Email where
44 { Doc.inlineLinkText =
45 [ eml & emailLocal & Doc.toInline
47 , eml & emailServer & Doc.toInline
50 , Doc.inlineLinkTarget =
62 -- newtype Organization = Organization (Tree.Tree (Role, Organization))
63 -- organization = Organization (Tree.Node ("", entity) [])
67 , orgParts :: [(Role, Organization)]
69 deriving (Eq, Ord, Show, Generic, NFData)
76 { entityId :: EntityId
77 , entityAddress :: Maybe Address
78 , entityEmail :: Maybe Email
79 , entityIBAN :: Maybe IBAN
80 , entityName :: Maybe Text
81 , entityPhone :: Maybe Phone
82 , entitySIREN :: Maybe Text
84 deriving (Eq, Ord, Show, Generic, NFData)
85 instance Doc.ToBlock Entity where
92 [ [ "Name" := addr & Doc.toBlock
93 | addr <- ent & entityName & maybeToList
95 , [ "Address" := addr & Doc.toBlock
96 | addr <- ent & entityAddress & maybeToList
98 , [ "SIREN" := siren & Doc.toBlock
99 | siren <- ent & entitySIREN & maybeToList
101 , [ "Email" := email & Doc.toBlock
102 | email <- ent & entityEmail & maybeToList
104 , [ "Phone" := phone & Doc.toBlock
105 | phone <- ent & entityPhone & maybeToList
107 , [ "IBAN" := iban & Doc.toBlock
108 | iban <- ent & entityIBAN & maybeToList
112 instance Doc.ToBlock Organization where
116 [ if (org & orgEntity) == entity then Doc.emptyBlock else Doc.toBlock $ org & orgEntity
119 [ role & Doc.toInline := part & Doc.toBlock
120 | (role, part) <- org & orgParts
125 | Text.null role = "" :: Doc.Inline
127 Doc.classes @Doc.Inline ["entity-role"] $
128 "(" <> Doc.toInline role <> ")"
131 { entityId = EntityId 0
132 , entityAddress = Nothing
133 , entityEmail = Nothing
134 , entityIBAN = Nothing
135 , entityName = Nothing
136 , entityPhone = Nothing
137 , entitySIREN = Nothing
140 data Address = Address
141 { addressText :: [Text]
142 , addressZipCode :: ZipCode
143 , addressCity :: City
144 , addressCountry :: Country.Country
146 deriving (Eq, Ord, Show, Generic, NFData)
147 instance Doc.ToBlock Address where
149 Doc.classes ["address"] $
153 | t <- addr & addressText
159 $ [ addr & addressZipCode & Doc.toInline
160 , addr & addressCity & Doc.toInline
161 , addr & addressCountry & Country.encodeEnglish & Doc.toInline
167 , addressZipCode = ""
169 , addressCountry = Country.france
175 -- | International Bank Account Number
177 { ibanCountry :: Country.Country
178 , ibanCheckDigits :: Natural
179 , ibanBasicBankAccountNumber :: Text
181 deriving (Eq, Ord, Show, Generic, NFData)
183 instance Doc.ToBlock IBAN where
185 [ iban & ibanCountry & Country.alphaTwoUpper & Doc.toInline
186 , iban & ibanCheckDigits & (Printf.printf "%02d" :: _ -> String) & Doc.toInline
188 , iban & ibanBasicBankAccountNumber & Text.chunksOf 4 & Text.intercalate " " & Doc.toInline