-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathimport_export.hs
More file actions
143 lines (139 loc) · 5.22 KB
/
import_export.hs
File metadata and controls
143 lines (139 loc) · 5.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
--This is one file with code written by me, but it is part of a project with a larger group of programmers.
module Handler.ImportExportSource where
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Map as Map
import Data.Text (Text)
import Handler.Xlsx
import Internet.Source.Types
( FullImportSource (..),
InternetProvider (..),
ImportSourceIdentification (..),
ImportSourceUUID (..),
)
import Prelude
-- Internet Source type without Group Id for parsing
data ParsedImportSource = ParsedImportSource
{ parsedImportSourceUUID :: ImportSourceUUID,
parsedImportSourceProvider :: InternetProvider,
parsedImportSourceIdentification :: [ImportSourceIdentification],
parsedImportSourceName :: Text,
parsedImportSourceCompanyIdRef :: CompanyIdRef
}
deriving (Show, Read, Eq, Ord)
instance XlsxRow ParsedImportSource where
toXlsxRow value rowIndex = do
Map.fromList $
zipWith
( \colIndex makeCell -> do
((rowIndex, colIndex), makeCell value)
)
[1 ..]
[ toXlsxCell . parsedImportSourceUUID,
toXlsxCell . parsedImportSourceProvider,
toXlsxCell . parsedImportSourceIdentification,
toXlsxCell . parsedImportSourceName,
toXlsxCell . parsedImportSourceCompanyIdRef
]
fromXlsxRow cellMap rowIndex = do
ParsedImportSource <$> parseWithDefault rowIndex 1 (ImportSourceUUID "")
<*> parseCell rowIndex 2
<*> parseWithDefault rowIndex 3 []
<*> parseCell rowIndex 4
<*> parseCell rowIndex 5
where
parseWithDefault rowIndex colIndex defaultVal = do
case Map.lookup (rowIndex, colIndex) cellMap of
Nothing -> Right $ defaultVal
Just cell ->
case fromXlsxCellSeparated cell of
Nothing -> Right $ defaultVal
Just cellVal ->
case fromXlsxCellValue cellVal of
Nothing -> Left $ "Invalid cell value: " ++ show cellVal
Just value -> Right $ value
parseCell rowIndex colIndex = do
case Map.lookup (rowIndex, colIndex) cellMap of
Nothing -> Left $ "Unable to parse cell " ++ show (rowIndex, colIndex)
Just cell ->
case fromXlsxCell cell of
Nothing -> Left $ "Unable to parse cell " ++ show (rowIndex, colIndex) ++ " with cell " ++ show cell
Just value -> Right $ value
instance XlsxSheet ParsedImportSource where
xlsxSheetHeaders =
[ "UUID",
"Provider",
"Identification",
"Name",
"Company ID"
]
styleXlsx = "./spreadsheetTemplates/ImportSourceExportTemplate.xlsx"
parsedToFullImportSource :: GroupId -> ParsedImportSource -> FullImportSource
parsedToFullImportSource
groupId
( ParsedImportSource
{ parsedImportSourceUUID,
parsedImportSourceProvider,
parsedImportSourceIdentification,
parsedImportSourceName,
parsedImportSourceCompanyIdRef
}
) =
FullImportSource
parsedImportSourceUUID
parsedImportSourceProvider
parsedImportSourceIdentification
parsedImportSourceName
groupId
parsedImportSourceCompanyIdRef
fullToParsedImportSource :: FullImportSource -> ParsedImportSource
fullToParsedImportSource
( FullImportSource
{ fullImportSourceUUID,
fullImportSourceProvider,
fullImportSourceIdentification,
fullImportSourceName,
fullImportSourceCompanyIdRef
}
) =
ParsedImportSource
fullImportSourceUUID
fullImportSourceProvider
fullImportSourceIdentification
fullImportSourceName
fullImportSourceCompanyIdRef
checkAllowableEmpty :: ParsedImportSource -> Bool
checkAllowableEmpty (ParsedImportSource {parsedImportSourceProvider, parsedImportSourceIdentification}) =
if parsedImportSourceIdentification == []
then case parsedImportSourceProvider of
UserProvided -> True
_ -> False
else True
exportFullImportSource :: [FullImportSource] -> IO (Either String LBS.ByteString)
exportFullImportSource fullSources = do
let sources = map fullToParsedImportSource fullSources
bytes <- toXlsxBytes $ sources
let parsedSources = fromXlsxBytes bytes
case parsedSources of
Left err -> do
return $ Left $ "Internal Error - Unable to parse the generated xlsx file: " ++ err
Right parsedSources' -> do
if sources == parsedSources'
then return $ Right bytes
else do
return $ Left $ "Internal Error - The generated file did not match the existing parameters: " ++ show (sources, parsedSources')
importFullImportSource :: GroupId -> LBS.ByteString -> Either String [FullImportSource]
importFullImportSource groupId bytes = do
case fromXlsxBytes @ParsedImportSource bytes of
Left err -> Left $ "Failed to parse XLSX file, " <> err
Right importedSourceSources ->
if all checkAllowableEmpty importedSourceSources
then
Right $
parsedToFullImportSource
groupId
`map` importedSourceSources
else Left $ "Error: Empty Internet Identification is only allowable for User Provided Internet Provider"