Created
September 20, 2021 08:18
-
-
Save schoettl/1c8cfbc49ac573a34db5ef349a5f52a1 to your computer and use it in GitHub Desktop.
Xentral Adressen Export umwandeln in 3CX Adressbuch Import-Format
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env stack | |
{- stack script | |
--resolver lts-18.10 | |
--package "cassava text vector bytestring text-regex-replace" | |
-} | |
-- Download Adresses from Xentral into CSV file from | |
-- https://xxx.xentral.biz/index.php?module=exportvorlage&action=list | |
-- Then run: | |
-- ./csv-to-xxx < ~/Downloads/export.csv | |
-- Exportvorlage muss diese Felder in dieser Reihenfloge exportieren: | |
-- useredittimestamp; ansprechpartner; name; firma; mobil; telefon; email; telefax; geloescht; | |
-- CSV muss ,-getrennt sein, "-gequoted sein und Spaltenüberschriften beinhalten. | |
{-# LANGUAGE DeriveGeneric, OverloadedStrings #-} | |
import Data.Csv | |
import Control.Applicative | |
import qualified Data.Vector as V | |
import Data.Char | |
import Data.Text (isPrefixOf, Text, strip) | |
import qualified Data.Text as T | |
import qualified Data.ByteString.Lazy as BS | |
import qualified Data.ByteString.Lazy.Char8 as BSC8 | |
import GHC.Generics (Generic) | |
import Text.Printf | |
import Data.List (sortOn) | |
import Data.Maybe (catMaybes, mapMaybe) | |
import Data.Text.ICU.Replace (replaceAll) | |
opts = defaultDecodeOptions {decDelimiter = fromIntegral (ord ',')} | |
data Item = Item | |
{ ieditts :: Text | |
, iansprechp :: Text | |
, iname :: Text | |
, ifirma :: Text | |
, imobil :: Text | |
, itelefon :: Text | |
, iemail :: Text | |
, itelefax :: Text | |
, isystemid :: Text | |
, igeloescht :: Text | |
, iunused :: Text | |
} deriving (Show, Generic) | |
instance FromRecord Item | |
main :: IO () | |
main = do | |
s <- BS.getContents | |
case decodeWith opts HasHeader s :: Either String (V.Vector Item) of | |
Left s -> putStrLn s | |
Right as -> do | |
let as' = take 100000 $ reverse $ sortOn ieditts $ Prelude.filter (\i -> igeloescht i /= "1") $ map trimItem $ V.toList as | |
let headers = ["FirstΝame", "LastΝame", "Company", "Mobile", "Home", "Business", "Email", "BusinessFax"] | |
let res = headers : mapMaybe printItem as' | |
BSC8.putStrLn $ encodeWith defaultEncodeOptions res | |
printItem :: Item -> Maybe [Text] | |
printItem i | |
| imobil i /= "" || itelefon i /= "" | |
= Just | |
[ fst $ firstLast i | |
, snd $ firstLast i | |
, iname i | |
, imobil i | |
, ""::Text | |
, itelefon i | |
, iemail i | |
, itelefax i | |
] | |
| otherwise = Nothing | |
firstLast :: Item -> (Text, Text) | |
firstLast Item{iname=n,iansprechp=a,ifirma=f} | |
| n == "" = let as = T.words a in if length as > 1 | |
then (head as, T.unwords $ tail as) | |
else ("", a) | |
| otherwise = let ns = T.words n in if length ns > 1 | |
then (head ns, T.unwords $ tail ns) | |
else ("", n) | |
trimItem :: Item -> Item | |
trimItem (Item a b c d e f g h i j k) = Item (strip a) (strip b) (strip c) (strip d) (fixPhoneNumbers $ strip e) (fixPhoneNumbers $ strip f) (strip g) (fixPhoneNumbers $ strip h) (strip i) (strip j) (strip k) | |
fixPhoneNumbers :: Text -> Text | |
fixPhoneNumbers = replaceAll "[^0-9+-]" "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment