FEA: finished approve method in event_billig. Finished event billing module
This commit is contained in:
parent
709dd54052
commit
f72dab60a9
|
@ -56,6 +56,12 @@ dependencies = [
|
|||
"opaque-debug 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
|
@ -73,9 +79,9 @@ checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
|||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
|
||||
|
||||
[[package]]
|
||||
name = "async-stream"
|
||||
|
@ -147,6 +153,17 @@ version = "0.13.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||
|
||||
[[package]]
|
||||
name = "bigdecimal"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1374191e2dd25f9ae02e3aa95041ed5d747fc77b3c102b49fe2dd9a8117a6244"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "binascii"
|
||||
version = "0.1.4"
|
||||
|
@ -161,9 +178,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
|||
|
||||
[[package]]
|
||||
name = "blake2b_simd"
|
||||
version = "0.5.11"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
|
||||
checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
|
@ -250,8 +267,8 @@ checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
|||
dependencies = [
|
||||
"libc",
|
||||
"num-integer",
|
||||
"num-traits 0.2.14",
|
||||
"serde 1.0.125",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"time 0.1.43",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
@ -289,15 +306,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "config"
|
||||
version = "0.11.0"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369"
|
||||
checksum = "54ad70579325f1a38ea4c13412b82241c5900700a69785d73e2736bd65a33f86"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"json5",
|
||||
"lazy_static",
|
||||
"nom",
|
||||
"pathdiff",
|
||||
"ron",
|
||||
"rust-ini",
|
||||
"serde 1.0.125",
|
||||
"serde-hjson",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"toml",
|
||||
"yaml-rust",
|
||||
|
@ -348,6 +368,22 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.1.4"
|
||||
|
@ -440,14 +476,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "diesel"
|
||||
version = "1.4.6"
|
||||
version = "1.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "047bfc4d5c3bd2ef6ca6f981941046113524b9a9f9a7cbdfdd7ff40f58e6f542"
|
||||
checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"chrono",
|
||||
"diesel_derives",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"pq-sys",
|
||||
"serde_json",
|
||||
"uuid",
|
||||
|
@ -498,6 +538,15 @@ version = "1.0.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||
|
||||
[[package]]
|
||||
name = "dlv-list"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68df3f2b690c1b86e65ef7830956aededf3cb0a16f898f79b9a6f421a7b6211b"
|
||||
dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
|
@ -528,9 +577,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.8.3"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f"
|
||||
checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
|
@ -544,6 +593,7 @@ name = "errms"
|
|||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bigdecimal",
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"config",
|
||||
|
@ -552,12 +602,13 @@ dependencies = [
|
|||
"email-address-parser",
|
||||
"env_logger",
|
||||
"iban_validate",
|
||||
"lettre",
|
||||
"log",
|
||||
"rand",
|
||||
"rocket",
|
||||
"rocket_dyn_templates",
|
||||
"rust-argon2",
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"uuid",
|
||||
|
@ -569,6 +620,15 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "figment"
|
||||
version = "0.10.5"
|
||||
|
@ -577,7 +637,7 @@ checksum = "0ca029e813a72b7526d28273d25f3e4a2f365d1b7a1018a6f93ec9053a119763"
|
|||
dependencies = [
|
||||
"atomic",
|
||||
"pear",
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
"toml",
|
||||
"uncased",
|
||||
"version_check",
|
||||
|
@ -601,6 +661,21 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "fsevent"
|
||||
version = "0.4.0"
|
||||
|
@ -818,7 +893,7 @@ dependencies = [
|
|||
"pest",
|
||||
"pest_derive",
|
||||
"quick-error",
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
|
@ -827,6 +902,9 @@ name = "hashbrown"
|
|||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
|
@ -857,6 +935,17 @@ dependencies = [
|
|||
"digest 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hostname"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"match_cfg",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.4"
|
||||
|
@ -865,7 +954,7 @@ checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
|
|||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
"itoa 0.4.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -912,7 +1001,7 @@ dependencies = [
|
|||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"itoa 0.4.7",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
|
@ -923,13 +1012,24 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "iban_validate"
|
||||
version = "4.0.0"
|
||||
version = "4.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae1dbb2046534ff3eda29fa47148f3e28011cbaf063dd5893edf89f47c3fe115"
|
||||
checksum = "cc1d358f7ae89819e8656f1b495c9d760a9ca315998b12d589dc516c9f81ed08"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.6.2"
|
||||
|
@ -938,7 +1038,7 @@ checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -991,6 +1091,23 @@ version = "0.4.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||
|
||||
[[package]]
|
||||
name = "json5"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
|
@ -1014,23 +1131,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "lexical-core"
|
||||
version = "0.7.6"
|
||||
name = "lettre"
|
||||
version = "0.10.0-rc.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
|
||||
checksum = "71d8da8f34d086b081c9cc3b57d3bb3b51d16fc06b5c848a188e2f14d58ac2a5"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags",
|
||||
"cfg-if 1.0.0",
|
||||
"ryu",
|
||||
"static_assertions",
|
||||
"async-trait",
|
||||
"base64",
|
||||
"fastrand",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"hostname",
|
||||
"httpdate",
|
||||
"idna",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"nom",
|
||||
"once_cell",
|
||||
"quoted_printable",
|
||||
"regex",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.94"
|
||||
version = "0.2.119"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
|
@ -1065,7 +1193,7 @@ dependencies = [
|
|||
"cfg-if 1.0.0",
|
||||
"generator",
|
||||
"scoped-tls",
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
|
@ -1075,6 +1203,18 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
||||
|
||||
[[package]]
|
||||
name = "match_cfg"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
|
@ -1087,6 +1227,12 @@ version = "0.3.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.6.23"
|
||||
|
@ -1173,6 +1319,24 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net2"
|
||||
version = "0.2.37"
|
||||
|
@ -1186,12 +1350,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "5.1.2"
|
||||
version = "7.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
|
||||
checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109"
|
||||
dependencies = [
|
||||
"lexical-core",
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
|
@ -1231,6 +1395,17 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
|
@ -1238,16 +1413,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||
dependencies = [
|
||||
"num-traits 0.2.14",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1287,6 +1453,49 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if 1.0.0",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-multimap"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c672c7ad9ec066e428c00eb917124a06f08db19e2584de982cc34b1f4c12485"
|
||||
dependencies = [
|
||||
"dlv-list",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.1"
|
||||
|
@ -1321,6 +1530,12 @@ dependencies = [
|
|||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||
|
||||
[[package]]
|
||||
name = "pear"
|
||||
version = "0.2.3"
|
||||
|
@ -1444,6 +1659,12 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
||||
|
||||
[[package]]
|
||||
name = "polyval"
|
||||
version = "0.4.5"
|
||||
|
@ -1529,15 +1750,20 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.3"
|
||||
name = "quoted_printable"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
|
||||
checksum = "3fee2dce59f7a43418e3382c766554c614e06a552d53a8f07ef499ea4b332c0f"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1559,15 +1785,6 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.7"
|
||||
|
@ -1649,7 +1866,7 @@ dependencies = [
|
|||
"ref-cast",
|
||||
"rocket_codegen",
|
||||
"rocket_http",
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"state",
|
||||
"tempfile",
|
||||
|
@ -1690,7 +1907,7 @@ dependencies = [
|
|||
"normpath",
|
||||
"notify",
|
||||
"rocket",
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
|
@ -1713,7 +1930,7 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"ref-cast",
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"stable-pattern",
|
||||
"state",
|
||||
|
@ -1724,10 +1941,21 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-argon2"
|
||||
version = "0.8.3"
|
||||
name = "ron"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
|
||||
checksum = "1b861ecaade43ac97886a512b360d01d66be9f41f3c61088b42cedf92e03d678"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bitflags",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-argon2"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b50162d19404029c1ceca6f6980fe40d45c8b369f6f44446fa14bb39573b5bb9"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"blake2b_simd",
|
||||
|
@ -1737,9 +1965,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rust-ini"
|
||||
version = "0.13.0"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"
|
||||
checksum = "63471c4aa97a1cf8332a5f97709a79a4234698de6a1f5087faf66f2dae810e22"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"ordered-multimap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
|
@ -1771,6 +2003,16 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.0"
|
||||
|
@ -1783,6 +2025,29 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
|
@ -1800,36 +2065,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "0.8.23"
|
||||
version = "1.0.136"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.125"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
|
||||
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-hjson"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"num-traits 0.1.43",
|
||||
"regex",
|
||||
"serde 0.8.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.125"
|
||||
version = "1.0.136"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
|
||||
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1838,13 +2085,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.64"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||
checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"itoa 1.0.1",
|
||||
"ryu",
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1948,12 +2195,6 @@ dependencies = [
|
|||
"loom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "stdweb"
|
||||
version = "0.4.20"
|
||||
|
@ -1976,7 +2217,7 @@ checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"syn",
|
||||
]
|
||||
|
@ -1990,7 +2231,7 @@ dependencies = [
|
|||
"base-x",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"sha1",
|
||||
|
@ -2091,6 +2332,21 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.6.2"
|
||||
|
@ -2121,6 +2377,16 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.6"
|
||||
|
@ -2152,7 +2418,7 @@ version = "0.5.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||
dependencies = [
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2209,7 +2475,7 @@ version = "0.10.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42756bb9e708855de2f8a98195643dff31a97f0485d90d8467b39dc24be9e8fe"
|
||||
dependencies = [
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2224,7 +2490,7 @@ version = "0.9.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5baeed7327e25054889b9bd4f975f32e5f4c5d434042d59ab6cd4142c0a76ed0"
|
||||
dependencies = [
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
|
@ -2234,6 +2500,21 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
|
@ -2257,7 +2538,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"serde 1.0.125",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
{{#if organiser.phone}}<p><b>Telefon: </b>{{organiser.phone}}</p>{{/if}}
|
||||
{{#if organiser.email}}<p><b>Email: </b>{{organiser.email}}</p>{{/if}}
|
||||
{{#if organiser.other}}<p><b>Sonstiges: </b>{{organiser.other}}</p>{{/if}}
|
||||
<h5>Abrechnung</h5>
|
||||
<p><b>Status:</b> {{state_name}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<div class="form-group row eu_cast_instance_personal_position" data-instance-id="{{../instance_id}}"
|
||||
data-position-id="{{position_id}}" data-member-name="{{member_name}}"
|
||||
data-member-id="{{taken_by}}">
|
||||
<label class="col-4 col-form-label" position_description}}title="{{position_description}}" {{{{#if/if}}>{{position_name}}</label>
|
||||
<label class="col-4 col-form-label" position_description}}title="{{position_description}}" {{ {{#if/if}}>{{position_name}}</label>
|
||||
<div class="input-group mb-3 col-8">
|
||||
{{#if taken_by}}{{member_name}}{{else}}
|
||||
<button class="btn btn-block btn-sm btn-secondary eu_cast_instance_self_register">Eintragen
|
||||
|
|
|
@ -121,15 +121,27 @@ EventListModule = ( function() {
|
|||
}
|
||||
|
||||
let date = new Date(event.start);
|
||||
event.timeframe = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth()+1)).slice(-2) + '.' + date.getFullYear() + ' ' + ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2) + ' - ';
|
||||
event.timeframe = ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear() + ' ' + ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2) + ' - ';
|
||||
let date2 = new Date(event.end);
|
||||
if(date.getDate() === date2.getDate()){
|
||||
if (date.getDate() === date2.getDate()) {
|
||||
event.timeframe += ('0' + date2.getHours()).slice(-2) + ':' + ('0' + date2.getMinutes()).slice(-2)
|
||||
}else{
|
||||
event.timeframe += event.timeframe = ('0' + date2.getDate()).slice(-2) + '.' + ('0' + (date2.getMonth()+1)).slice(-2) + '.' + date2.getFullYear() + ' ' + ('0' + date2.getHours()).slice(-2) + ':' + ('0' + date2.getMinutes()).slice(-2);
|
||||
} else {
|
||||
event.timeframe += event.timeframe = ('0' + date2.getDate()).slice(-2) + '.' + ('0' + (date2.getMonth() + 1)).slice(-2) + '.' + date2.getFullYear() + ' ' + ('0' + date2.getHours()).slice(-2) + ':' + ('0' + date2.getMinutes()).slice(-2);
|
||||
}
|
||||
|
||||
event.cast_status = await load_event_cast_status(event.entity_id);
|
||||
event.state_name = "unbekannt";
|
||||
if (event.state === 2) {
|
||||
event.state_name = "Einsatz geöffnet";
|
||||
} else if (event.state === 4) {
|
||||
event.state_name = "Einsatz geschlossen";
|
||||
} else if (event.state === 6) {
|
||||
event.state_name = "Einsatzzeiten bestätigt";
|
||||
} else if (event.state === 7) {
|
||||
event.state_name = "Personalabrechnung abgeschlossen";
|
||||
} else if (event.state === 8) {
|
||||
event.state_name = "Abrechnung abgeschlossen";
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
|
|
|
@ -724,12 +724,8 @@ EventBilling = (function () {
|
|||
contentType: 'application/json',
|
||||
timeout: 3000,
|
||||
});
|
||||
if ('error' in data) {
|
||||
if (data.error.code === 404) {
|
||||
return undefined;
|
||||
} else {
|
||||
show_error(data)
|
||||
}
|
||||
if (!is_ok(data)) {
|
||||
show_error(data)
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
v0.2-84-g27295c7
|
||||
v0.2-96-g136781c
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use bigdecimal::BigDecimal;
|
||||
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||
use diesel::{ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl};
|
||||
use rocket::State;
|
||||
|
||||
use crate::database::controller::connector::establish_connection;
|
||||
|
@ -45,10 +45,10 @@ pub fn create(settings: &State<Settings>, data: RawPersonnelBilling) -> Result<(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read(settings: &State<Settings>, position_instance_id: uuid::Uuid) -> Result<RawPersonnelBilling, diesel::result::Error> {
|
||||
pub fn read(settings: &State<Settings>, position_instance_id: uuid::Uuid) -> Result<Option<RawPersonnelBilling>, diesel::result::Error> {
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match personnel_billing::table.filter(personnel_billing::dsl::position_instance_id.eq(position_instance_id)).get_result(&connection) {
|
||||
match personnel_billing::table.filter(personnel_billing::dsl::position_instance_id.eq(position_instance_id)).get_result(&connection).optional() {
|
||||
Ok(res) => Ok(res),
|
||||
Err(e) => {
|
||||
error!("Couldn't get personnel billing details: {}", e);
|
||||
|
|
|
@ -10,7 +10,7 @@ pub struct BillingState {
|
|||
entity_id: uuid::Uuid,
|
||||
name: String,
|
||||
description: Option<String>,
|
||||
final_approve: bool,
|
||||
pub(crate) final_approve: bool,
|
||||
}
|
||||
|
||||
pub fn get_billing_states(settings: &State<Settings>) -> Result<Vec<BillingState>, diesel::result::Error> {
|
||||
|
@ -27,6 +27,20 @@ pub fn get_billing_states(settings: &State<Settings>) -> Result<Vec<BillingState
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_billing_state(settings: &State<Settings>, state: uuid::Uuid) -> Result<BillingState, diesel::result::Error> {
|
||||
use crate::schema::billing_states::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match billing_states.select((entity_id, name, description, final_approve)).filter(entity_id.eq(state)).get_result(&connection) {
|
||||
Ok(bs) => Ok(bs),
|
||||
Err(e) => {
|
||||
error!("Couldn't get billing state: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_billing_states_for_event(settings: &State<Settings>, event: uuid::Uuid) -> Result<Vec<uuid::Uuid>, diesel::result::Error> {
|
||||
use crate::schema::eu_instances::dsl::*;
|
||||
|
||||
|
|
|
@ -98,6 +98,23 @@ pub fn approve_stage(settings: &State<Settings>, event_id2: uuid::Uuid, stage: u
|
|||
}
|
||||
}
|
||||
|
||||
/// Sets state for event from 7 to 8
|
||||
/// Used in API endpoint for billing module
|
||||
/// Returns an empty Ok result or an [diesel::result::Error].
|
||||
pub fn finish_billing(settings: &State<Settings>, event_id: uuid::Uuid) -> Result<(), diesel::result::Error> {
|
||||
use crate::schema::events::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match diesel::update(events.filter(entity_id.eq(event_id)).filter(state.eq(7))).set(state.eq(8)).execute(&connection) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
error!("Couldn't finish billing: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn change_event(settings: &State<Settings>, data: Event) -> Result<Event, diesel::result::Error> {
|
||||
use crate::schema::events::dsl::*;
|
||||
|
||||
|
@ -510,7 +527,7 @@ pub fn get_instance_positions_name_description(settings: &State<Settings>, insta
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_instance_positions(settings: &State<Settings>, instance_id: uuid::Uuid) -> Result<Vec<RawPositionInstance>, diesel::result::Error> {
|
||||
pub fn get_position_instances(settings: &State<Settings>, instance_id: uuid::Uuid) -> Result<Vec<RawPositionInstance>, diesel::result::Error> {
|
||||
let connection = establish_connection(settings);
|
||||
|
||||
match eu_position_instances.filter(crate::schema::eu_position_instances::dsl::instance_id.eq(instance_id)).get_results(&connection) {
|
||||
|
|
|
@ -37,6 +37,20 @@ pub fn get_instances(settings: &State<Settings>, event: uuid::Uuid) -> Result<Ve
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_instance(settings: &State<Settings>, instance: uuid::Uuid) -> Result<RawEventUnitInstance, diesel::result::Error> {
|
||||
use crate::schema::eu_instances::dsl::*;
|
||||
|
||||
let connection = establish_connection(settings);
|
||||
match eu_instances.filter(instance_id.eq(instance)).get_result(&connection) {
|
||||
Ok(instances) => Ok(instances),
|
||||
Err(e) => {
|
||||
error!("Couldn't get event unit instance: {}", e);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Queryable, Clone, Deserialize, Serialize, AsChangeset, Insertable)]
|
||||
#[table_name = "eu_instances"]
|
||||
#[primary_key(entity_id)]
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
use diesel::{JoinOnDsl, QueryDsl, sql_query};
|
||||
use diesel::pg::expression::array_comparison::any;
|
||||
use diesel::pg::types::sql_types::{Array, Uuid};
|
||||
use diesel::sql_types::{BigInt, Text};
|
||||
use rocket::State;
|
||||
|
||||
use crate::database::controller::connector::establish_connection;
|
||||
use crate::database::controller::groups::get_groups_for_member;
|
||||
use crate::database::model::members::RawMember;
|
||||
use crate::diesel::prelude::*;
|
||||
use crate::helper::settings::Settings;
|
||||
use crate::modules::member_management::model::member::Member;
|
||||
use diesel::pg::expression::array_comparison::any;
|
||||
use diesel::pg::types::sql_types::{Uuid, Array};
|
||||
use diesel::sql_types::{BigInt, Text};
|
||||
use diesel::{sql_query, JoinOnDsl, QueryDsl};
|
||||
use rocket::State;
|
||||
use crate::schema::groups_entities::dsl::groups_entities;
|
||||
|
||||
/*impl<DB> FromSql<SmallInt, DB> for Sex
|
||||
|
@ -240,6 +241,7 @@ pub fn get_members_by_user_uuid(uuid: uuid::Uuid, settings: &State<Settings>) ->
|
|||
/// * 'settings' - Settings, as managed State
|
||||
/// #Returns
|
||||
/// * 'Member'
|
||||
//TODO: return Result not OPtion
|
||||
pub fn get_member_by_uuid(uuid: uuid::Uuid, settings: &State<Settings>) -> Option<Member> {
|
||||
let raw_member: RawMember = get_raw_member_by_uuid(uuid, &settings)?;
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ pub fn create_event(
|
|||
other: ecd.other,
|
||||
other_intern: ecd.other_intern,
|
||||
related_request: None,
|
||||
state: 0
|
||||
state: 2
|
||||
};
|
||||
|
||||
match add_event(settings, input){
|
||||
|
|
|
@ -68,7 +68,7 @@ pub fn create_instance(
|
|||
};
|
||||
|
||||
let planned_start_time = match cid.planned_start_time {
|
||||
Some(dt) => match datetime_str_to_utc(settings, &cookie, &dt) {
|
||||
Some(dt) => match datetime_str_to_utc(settings, Some(&cookie), &dt) {
|
||||
Ok(dt) => Some(dt),
|
||||
Err(e) => {
|
||||
warn!("Couldn't parse planned start time as DateTime: {}", e);
|
||||
|
@ -82,7 +82,7 @@ pub fn create_instance(
|
|||
};
|
||||
|
||||
let planned_end_time = match cid.planned_end_time {
|
||||
Some(dt) => match datetime_str_to_utc(settings, &cookie, &dt) {
|
||||
Some(dt) => match datetime_str_to_utc(settings, Some(&cookie), &dt) {
|
||||
Ok(dt) => Some(dt),
|
||||
Err(e) => {
|
||||
warn!("Couldn't parse planned end time as DateTime: {}", e);
|
||||
|
@ -177,7 +177,7 @@ pub fn add_position_instance(
|
|||
}
|
||||
//TODO: require extra permissions to set real start time & real end time
|
||||
let real_start_time = match create_position_instance_data.real_start_time {
|
||||
Some(dt) => match datetime_str_to_utc(settings, &cookie, &dt) {
|
||||
Some(dt) => match datetime_str_to_utc(settings, Some(&cookie), &dt) {
|
||||
Ok(dt) => Some(dt),
|
||||
Err(e) => {
|
||||
warn!("Couldn't parse real start time as DateTime: {}", e);
|
||||
|
@ -190,7 +190,7 @@ pub fn add_position_instance(
|
|||
None => None,
|
||||
};
|
||||
let real_end_time = match create_position_instance_data.real_end_time {
|
||||
Some(dt) => match datetime_str_to_utc(settings, &cookie, &dt) {
|
||||
Some(dt) => match datetime_str_to_utc(settings, Some(&cookie), &dt) {
|
||||
Ok(end) => {
|
||||
if let Some(start) = real_start_time {
|
||||
if start.ge(&end) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
|
||||
use crate::database::controller::events::{get_eu_position, get_instance_positions, get_instance_vehicle_positions};
|
||||
use crate::database::controller::events::{get_eu_position, get_instance_vehicle_positions, get_position_instances};
|
||||
use crate::database::controller::events::instances::instance_positions::RawPositionInstance;
|
||||
use crate::database::controller::events::instances::instances::{get_instances, RawEventUnitInstance};
|
||||
use crate::database::model::events::{EventUnitInstanceDeprecated, EventUnitInstancePosition, EventUnitInstanceVehiclePosition};
|
||||
|
@ -33,19 +33,19 @@ impl EventUnitInstance {
|
|||
/// Convert RawEventUnitInstance to EventUnitInstance by converting Utc DateTimes to timestamps with user specified timezone
|
||||
pub fn from_raw(raw: RawEventUnitInstance, settings: &State<Settings>, cookie: &SessionCookie) -> EventUnitInstance {
|
||||
let planned_start_time = match raw.planned_start_time {
|
||||
Some(dt) => Some(utc_to_local_user_time(settings, cookie, dt)),
|
||||
Some(dt) => Some(utc_to_local_user_time(settings, Some(cookie), dt)),
|
||||
None => None
|
||||
};
|
||||
let planned_end_time = match raw.planned_end_time {
|
||||
Some(dt) => Some(utc_to_local_user_time(settings, cookie, dt)),
|
||||
Some(dt) => Some(utc_to_local_user_time(settings, Some(cookie), dt)),
|
||||
None => None
|
||||
};
|
||||
let real_start_time = match raw.real_start_time {
|
||||
Some(dt) => Some(utc_to_local_user_time(settings, cookie, dt)),
|
||||
Some(dt) => Some(utc_to_local_user_time(settings, Some(cookie), dt)),
|
||||
None => None
|
||||
};
|
||||
let real_end_time = match raw.real_end_time {
|
||||
Some(dt) => Some(utc_to_local_user_time(settings, cookie, dt)),
|
||||
Some(dt) => Some(utc_to_local_user_time(settings, Some(cookie), dt)),
|
||||
None => None
|
||||
};
|
||||
|
||||
|
@ -83,11 +83,11 @@ impl PositionInstance {
|
|||
/// Convert RawPositionInstance to PositionInstance by converting Utc DateTimes to timestamps with user specified timezone
|
||||
pub fn from_raw(raw: &RawPositionInstance, settings: &State<Settings>, cookie: &SessionCookie) -> Result<PositionInstance, ()> {
|
||||
let real_start_time = match raw.real_start_time {
|
||||
Some(dt) => Some(utc_to_local_user_time(settings, cookie, dt)),
|
||||
Some(dt) => Some(utc_to_local_user_time(settings, Some(cookie), dt)),
|
||||
None => None
|
||||
};
|
||||
let real_end_time = match raw.real_end_time {
|
||||
Some(dt) => Some(utc_to_local_user_time(settings, cookie, dt)),
|
||||
Some(dt) => Some(utc_to_local_user_time(settings, Some(cookie), dt)),
|
||||
None => None
|
||||
};
|
||||
let position_data = match get_eu_position(settings, raw.position_id) {
|
||||
|
@ -159,7 +159,7 @@ pub fn read_positions_for_instance(settings: &State<Settings>, cookie: SessionCo
|
|||
return Err(Json(ApiError::new(403, "Keine Berechtigung Einsätze abzurufen!".to_string()).to_wrapper()));
|
||||
}
|
||||
|
||||
match get_instance_positions(settings, parse_uuid_string(instance_id)?) {
|
||||
match get_position_instances(settings, parse_uuid_string(instance_id)?) {
|
||||
Ok(pos) => {
|
||||
let mut res = vec![];
|
||||
for position in pos {
|
||||
|
|
|
@ -5,7 +5,7 @@ use rocket::State;
|
|||
|
||||
use crate::database::controller::events::{change_position_instances, get_event};
|
||||
use crate::database::controller::events::instances::instance_positions::RawPositionInstanceChangeset;
|
||||
use crate::database::controller::events::instances::instances::{RawEventUnitInstanceChangeset, update_instance};
|
||||
use crate::database::controller::events::instances::instances::{get_instance, get_instances, RawEventUnitInstanceChangeset, update_instance};
|
||||
use crate::helper::serde_patch::Patch;
|
||||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use crate::helper::settings::Settings;
|
||||
|
@ -28,11 +28,33 @@ pub fn put_entity_in_position(
|
|||
|
||||
let position_id = parse_uuid_string(position_id)?;
|
||||
let entity_id = parse_uuid_string(entity_id)?;
|
||||
let instance_id = parse_uuid_string(instance_id)?;
|
||||
|
||||
let instance = match get_instance(settings, instance_id) {
|
||||
Ok(instance) => instance,
|
||||
Err(e) =>
|
||||
{
|
||||
warn!("Instance not found: {}", e);
|
||||
return Err(Json(ApiError::new(404, "instance not found!".to_string()).to_wrapper()));
|
||||
}
|
||||
};
|
||||
let event = match get_event(settings, instance.event_id) {
|
||||
Ok(event) => event,
|
||||
Err(e) => {
|
||||
warn!("Event not found: {}", e);
|
||||
return Err(Json(
|
||||
ApiError::new(404, "event for instance not found!".to_string()).to_wrapper()))
|
||||
}
|
||||
};
|
||||
if event.state >= 4 {
|
||||
return Err(Json(
|
||||
ApiError::new(400, "Dieser Einsatz wurde bereits geschlossen!".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
if caller.entity_id == entity_id {
|
||||
match check_position_requirements(settings, position_id, entity_id){
|
||||
match check_position_requirements(settings, position_id, entity_id) {
|
||||
Ok(res) => {
|
||||
if !res{ //if member tries to add himself to a position, but don't fulfill the position requirements AND don't have the event edit permission (overwrite), abort
|
||||
if !res { //if member tries to add himself to a position, but don't fulfill the position requirements AND don't have the event edit permission (overwrite), abort
|
||||
if !caller.has_permission(crate::permissions::modules::event_management::events::EDIT.to_string()) {
|
||||
return Err(Json(
|
||||
ApiError::new(403, "Keine Berechtigung Einsätze zu bearbeiten!".to_string()).to_wrapper(),
|
||||
|
@ -52,15 +74,13 @@ pub fn put_entity_in_position(
|
|||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if !caller.has_permission(crate::permissions::modules::event_management::events::EDIT.to_string()) {
|
||||
return Err(Json(
|
||||
ApiError::new(403, "Keine Berechtigung Einsätze zu bearbeiten!".to_string()).to_wrapper(),
|
||||
));
|
||||
}
|
||||
} else if !caller.has_permission(crate::permissions::modules::event_management::events::EDIT.to_string()) {
|
||||
return Err(Json(
|
||||
ApiError::new(403, "Keine Berechtigung Einsätze zu bearbeiten!".to_string()).to_wrapper(),
|
||||
));
|
||||
}
|
||||
|
||||
match change_position_instances(settings, parse_uuid_string(instance_id)?, position_id, Some(entity_id)){
|
||||
match change_position_instances(settings, instance_id, position_id, Some(entity_id)) {
|
||||
Ok(pos) => Ok(Json(pos)),
|
||||
Err(e) => return Err(translate_diesel(e))
|
||||
}
|
||||
|
@ -80,7 +100,30 @@ pub fn remove_entity_from_position(
|
|||
));
|
||||
}
|
||||
|
||||
match change_position_instances(settings, parse_uuid_string(instance_id)?, parse_uuid_string(position_id)?, None) {
|
||||
let instance_id = parse_uuid_string(instance_id)?;
|
||||
|
||||
let instance = match get_instance(settings, instance_id) {
|
||||
Ok(instance) => instance,
|
||||
Err(e) =>
|
||||
{
|
||||
warn!("Instance not found: {}", e);
|
||||
return Err(Json(ApiError::new(404, "instance not found!".to_string()).to_wrapper()));
|
||||
}
|
||||
};
|
||||
let event = match get_event(settings, instance.event_id) {
|
||||
Ok(event) => event,
|
||||
Err(e) => {
|
||||
warn!("Event not found: {}", e);
|
||||
return Err(Json(
|
||||
ApiError::new(404, "event for instance not found!".to_string()).to_wrapper()))
|
||||
}
|
||||
};
|
||||
if event.state >= 4 {
|
||||
return Err(Json(
|
||||
ApiError::new(400, "Dieser Einsatz wurde bereits geschlossen!".to_string()).to_wrapper()))
|
||||
}
|
||||
|
||||
match change_position_instances(settings, instance_id, parse_uuid_string(position_id)?, None) {
|
||||
Ok(pos) => Ok(Json(pos)),
|
||||
Err(e) => return Err(translate_diesel(e))
|
||||
}
|
||||
|
@ -182,7 +225,7 @@ pub fn patch_instance(
|
|||
Patch::Missing => None,
|
||||
Patch::Null => Some(None),
|
||||
Patch::Value(v) => {
|
||||
match datetime_str_to_utc(settings, &cookie, &v) {
|
||||
match datetime_str_to_utc(settings, Some(&cookie), &v) {
|
||||
Ok(v) => Some(Some(v)),
|
||||
Err(e) => {
|
||||
warn!("Couldn't parse planned start time as DateTime: {}",e);
|
||||
|
@ -197,7 +240,7 @@ pub fn patch_instance(
|
|||
Patch::Missing => None,
|
||||
Patch::Null => Some(None),
|
||||
Patch::Value(v) => {
|
||||
match datetime_str_to_utc(settings, &cookie, &v) {
|
||||
match datetime_str_to_utc(settings, Some(&cookie), &v) {
|
||||
Ok(v) => Some(Some(v)),
|
||||
Err(e) => {
|
||||
warn!("Couldn't parse planned end time as DateTime: {}",e);
|
||||
|
@ -212,7 +255,7 @@ pub fn patch_instance(
|
|||
Patch::Missing => None,
|
||||
Patch::Null => Some(None),
|
||||
Patch::Value(v) => {
|
||||
match datetime_str_to_utc(settings, &cookie, &v) {
|
||||
match datetime_str_to_utc(settings, Some(&cookie), &v) {
|
||||
Ok(v) => Some(Some(v)),
|
||||
Err(e) => {
|
||||
warn!("Couldn't parse real start time as DateTime: {}",e);
|
||||
|
@ -227,7 +270,7 @@ pub fn patch_instance(
|
|||
Patch::Missing => None,
|
||||
Patch::Null => Some(None),
|
||||
Patch::Value(v) => {
|
||||
match datetime_str_to_utc(settings, &cookie, &v) {
|
||||
match datetime_str_to_utc(settings, Some(&cookie), &v) {
|
||||
Ok(v) => Some(Some(v)),
|
||||
Err(e) => {
|
||||
warn!("Couldn't parse real end time as DateTime: {}",e);
|
||||
|
@ -312,7 +355,7 @@ pub fn patch_position_instance(
|
|||
Patch::Missing => None,
|
||||
Patch::Null => Some(None),
|
||||
Patch::Value(v) => {
|
||||
match datetime_str_to_utc(settings, &cookie, &v) {
|
||||
match datetime_str_to_utc(settings, Some(&cookie), &v) {
|
||||
Ok(v) => Some(Some(v)),
|
||||
Err(e) => {
|
||||
warn!("Couldn't parse real start time as DateTime: {}",e);
|
||||
|
@ -327,7 +370,7 @@ pub fn patch_position_instance(
|
|||
Patch::Missing => None,
|
||||
Patch::Null => Some(None),
|
||||
Patch::Value(v) => {
|
||||
match datetime_str_to_utc(settings, &cookie, &v) {
|
||||
match datetime_str_to_utc(settings, Some(&cookie), &v) {
|
||||
Ok(end) => {
|
||||
match real_start_time {
|
||||
Some(start) => match start {
|
||||
|
|
|
@ -3,7 +3,7 @@ use rocket::serde::json::Json;
|
|||
use rocket::State;
|
||||
|
||||
use crate::database::controller::billing::states::{get_billing_states_for_event, get_min_billing_states_for_event};
|
||||
use crate::database::controller::events::{get_event, get_event_count, get_events, get_events_for_member_in_future, get_instance_positions, get_instance_positions_name_description};
|
||||
use crate::database::controller::events::{get_event, get_event_count, get_events, get_events_for_member_in_future, get_instance_positions_name_description, get_position_instances};
|
||||
use crate::database::controller::events::instances::instances::get_instances;
|
||||
use crate::database::model::events::Event;
|
||||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use chrono::NaiveDateTime;
|
||||
use diesel::expression::ops::Mul;
|
||||
use lettre::{AsyncTransport, Message};
|
||||
use lettre::message::{Attachment, MultiPart, SinglePart};
|
||||
use lettre::message::header::ContentType;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
|
||||
use crate::database::controller::events::{change_event, get_event};
|
||||
use crate::database::controller::billing::states::{get_billing_state, get_billing_states};
|
||||
use crate::database::controller::events::{change_event, finish_billing, get_event};
|
||||
use crate::database::controller::events::instances::instance_positions::RawPositionInstanceChangeset;
|
||||
use crate::database::controller::events::instances::instances::get_instances;
|
||||
use crate::database::controller::members::check_access_to_resource;
|
||||
|
@ -10,9 +17,11 @@ use crate::database::model::events::Event;
|
|||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use crate::helper::settings::Settings;
|
||||
use crate::helper::translate_diesel_error::translate_diesel;
|
||||
use crate::MailQueue;
|
||||
use crate::modules::api::events::create::CreateEventData;
|
||||
use crate::modules::api::member_management::controller::parser::{parse_member_cookie, parse_option_uuid, parse_uuid_string};
|
||||
use crate::modules::api::model::api_outcome::{ApiError, ApiErrorWrapper};
|
||||
use crate::modules::event_billing::generate_billing_csv::{generate_billing_csv, save_billing_csv};
|
||||
|
||||
#[put("/api/events/<entity_id>", format = "json", data = "<update_event_data>")]
|
||||
pub fn update_event(
|
||||
|
@ -214,24 +223,57 @@ pub fn finish_personnel_billing(
|
|||
}
|
||||
|
||||
#[put("/api/events/<entity_id>/approve?<stage>", format = "json")]
|
||||
pub fn approve(
|
||||
pub async fn approve(
|
||||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
entity_id: String,
|
||||
stage: String,
|
||||
mq: &State<Arc<MailQueue>>,
|
||||
) -> Result<(), Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member)?;
|
||||
|
||||
let event_id = parse_uuid_string(entity_id)?;
|
||||
|
||||
let stage = parse_uuid_string(stage)?;
|
||||
let billing_state = match get_billing_state(settings, stage) {
|
||||
Ok(state) => state,
|
||||
Err(e) => {
|
||||
warn!("Couldn't find stage: {}", e);
|
||||
return Err(Json(ApiError::new(404, "Stage not found.".to_string()).to_wrapper()));
|
||||
}
|
||||
};
|
||||
|
||||
if !check_access_to_resource(settings, caller.entity_id, stage, crate::permissions::modules::event_billing::APPROVE) {
|
||||
return Err(Json(ApiError::new(403, "No permission to approve this billing state.".to_string()).to_wrapper()));
|
||||
}
|
||||
|
||||
match crate::database::controller::events::approve_stage(settings, event_id, stage, caller.entity_id) {
|
||||
Ok(_) => Ok(()),
|
||||
Ok(_) => {
|
||||
if billing_state.final_approve {
|
||||
if let Err(e) = finish_billing(settings, event_id) {
|
||||
return Err(translate_diesel(e));
|
||||
}
|
||||
let csv = match generate_billing_csv(settings, event_id) {
|
||||
Ok(csv) => csv,
|
||||
Err(e) => {
|
||||
error!("Error generating CSV: {}", e); //TODO: report failure to user
|
||||
return Ok(())
|
||||
}
|
||||
};
|
||||
debug!("Generated CSV: {}", csv);
|
||||
if settings.billing.send_personnel_billing_to_email {
|
||||
let attachement = Attachment::new(String::from("Einsatzabrechnung.csv")).body(csv, ContentType::parse("text/csv").unwrap());
|
||||
let msg = Message::builder()
|
||||
.from(settings.mail.from.clone().parse().unwrap())
|
||||
.reply_to(settings.mail.reply_to.clone().parse().unwrap())
|
||||
.to(settings.billing.personnel_billing_email.parse().unwrap())
|
||||
.subject("Einsatzabrechnung")
|
||||
.multipart(MultiPart::mixed().singlepart(attachement).singlepart(SinglePart::plain(String::from("Es wurde eine Einsatzabrechnung freigegeben. Sie befindet sich im Anhang dieser E-Mail.")))).unwrap();
|
||||
mq.add_mail(msg);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ use rocket::State;
|
|||
|
||||
use crate::database::controller::billing::personnel_billing::RawPersonnelBilling;
|
||||
use crate::database::controller::billing::personnel_billing_rates::{get_billing_rate, get_billing_rates};
|
||||
use crate::database::controller::events::{get_instance_positions, get_position_instance};
|
||||
use crate::database::controller::events::{get_position_instance, get_position_instances};
|
||||
use crate::helper::session_cookies::model::SessionCookie;
|
||||
use crate::helper::translate_diesel_error::translate_diesel;
|
||||
use crate::modules::api::member_management::controller::parser::{parse_member_cookie, parse_uuid_string};
|
||||
|
|
|
@ -26,7 +26,7 @@ pub fn get_personnel_billing(
|
|||
settings: &State<Settings>,
|
||||
cookie: SessionCookie,
|
||||
position_instance_id: String,
|
||||
) -> Result<Json<PersonnelBilling>, Json<ApiErrorWrapper>> {
|
||||
) -> Result<Json<Option<PersonnelBilling>>, Json<ApiErrorWrapper>> {
|
||||
let caller = parse_member_cookie(cookie.member.clone())?;
|
||||
//TODO: allow member_responsible for event to bypass this permission
|
||||
if !caller
|
||||
|
@ -44,15 +44,20 @@ pub fn get_personnel_billing(
|
|||
let pid = parse_uuid_string(position_instance_id)?;
|
||||
match crate::database::controller::billing::personnel_billing::read(settings, pid) {
|
||||
Ok(res) => {
|
||||
Ok(Json(PersonnelBilling {
|
||||
position_instance_id: res.position_instance_id,
|
||||
member_id: res.member_id,
|
||||
fulfilled_time: res.fulfilled_time,
|
||||
money_for_time: res.money_for_time.to_string(),
|
||||
money_from_lump_sum: res.money_from_lump_sum.to_string(),
|
||||
total_money: res.total_money.to_string(),
|
||||
Ok(Json(match res {
|
||||
Some(res) => {
|
||||
Some(PersonnelBilling {
|
||||
position_instance_id: res.position_instance_id,
|
||||
member_id: res.member_id,
|
||||
fulfilled_time: res.fulfilled_time,
|
||||
money_for_time: res.money_for_time.to_string(),
|
||||
money_from_lump_sum: res.money_from_lump_sum.to_string(),
|
||||
total_money: res.total_money.to_string(),
|
||||
})
|
||||
},
|
||||
None => None
|
||||
}))
|
||||
}
|
||||
},
|
||||
Err(e) => Err(translate_diesel(e))
|
||||
}
|
||||
}
|
|
@ -52,6 +52,12 @@ pub fn approve(cookie: SessionCookie, settings: &State<Settings>, event_id: Stri
|
|||
}
|
||||
};
|
||||
|
||||
//Do not allow editing times before event is closed
|
||||
if event.state < 7 {
|
||||
error!("User tried to approve before event was billed");
|
||||
return Err(Status::BadRequest);
|
||||
}
|
||||
|
||||
let header = Header {
|
||||
html_language: "de".to_string(),
|
||||
site_title: "Einsatzabrechnung".to_string(),
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
use std::fmt;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use rocket::State;
|
||||
|
||||
use crate::database::controller::billing::personnel_billing_rates::get_billing_rate;
|
||||
use crate::database::controller::events::{get_event, get_position_instance, get_position_instances};
|
||||
use crate::database::controller::events::instances::instances::get_instances;
|
||||
use crate::database::controller::groups::get_group;
|
||||
use crate::database::controller::members::get_member_by_uuid;
|
||||
use crate::helper::time::utc_to_local_user_time;
|
||||
use crate::modules::api::personnel_billing::read::get_personnel_billing;
|
||||
use crate::Settings;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub enum CSVGeneratorErrorKind {
|
||||
MissingTimes,
|
||||
MissingMember,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CSVGeneratorError {
|
||||
Database(diesel::result::Error),
|
||||
Generator(CSVGeneratorErrorKind),
|
||||
IoError(std::io::Error),
|
||||
}
|
||||
|
||||
impl CSVGeneratorErrorKind {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match *self {
|
||||
CSVGeneratorErrorKind::MissingTimes => "Missing real start and/or real end times.",
|
||||
CSVGeneratorErrorKind::MissingMember => "Missing member details. Maybe member got removed?",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CSVGeneratorError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
CSVGeneratorError::Generator(ref err) => write!(f, "CSV Generator error: {:?}", err),
|
||||
CSVGeneratorError::Database(ref err) => std::fmt::Display::fmt(&err, f),
|
||||
CSVGeneratorError::IoError(ref err) => std::fmt::Display::fmt(&err, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<diesel::result::Error> for CSVGeneratorError {
|
||||
fn from(err: diesel::result::Error) -> CSVGeneratorError {
|
||||
CSVGeneratorError::Database(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for CSVGeneratorError {
|
||||
fn from(err: std::io::Error) -> CSVGeneratorError {
|
||||
CSVGeneratorError::IoError(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save_billing_csv(settings: &State<Settings>, csv: String, event_name: String) -> Result<String, std::io::Error> {
|
||||
let mut path_draft = format!("data/personnel_billing_csv/csv_{}", event_name);
|
||||
let mut path = Path::new(&path_draft);
|
||||
|
||||
if path.exists() {
|
||||
let mut i = 1;
|
||||
loop {
|
||||
path_draft = format!("data/personnel_billing_csv/csv_{}_{}", event_name, i);
|
||||
if !Path::new(&path_draft).exists() {
|
||||
break;
|
||||
} else {
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
path = Path::new(&path_draft);
|
||||
}
|
||||
|
||||
let mut file = File::create(&path)?;
|
||||
file.write_all(csv.as_bytes())?;
|
||||
Ok(path_draft)
|
||||
}
|
||||
|
||||
pub fn generate_billing_csv(settings: &State<Settings>, event_id: uuid::Uuid) -> Result<String, CSVGeneratorError> {
|
||||
let mut res = String::new();
|
||||
|
||||
let event_data = get_event(settings, event_id)?;
|
||||
res.push_str(&format!("{}, {}\n", sanitize(String::from("Einsatz: ")), sanitize(event_data.name.clone())));
|
||||
|
||||
if let Some(related_group) = event_data.related_group {
|
||||
let group = get_group(settings, related_group)?;
|
||||
res.push_str(&format!("{}, {}\n", sanitize(String::from("Gruppe:")), sanitize(group.name)));
|
||||
}
|
||||
|
||||
if let Some(member_responsible) = event_data.member_responsible {
|
||||
if let Some(member) = get_member_by_uuid(member_responsible, settings) {
|
||||
res.push_str(&format!("{}, {}\n", sanitize(String::from("Verantwortliches Mitglied:")), sanitize(format!("{} {}", member.firstname, member.lastname))))
|
||||
}
|
||||
}
|
||||
|
||||
res.push_str("\n");
|
||||
|
||||
let instances = get_instances(settings, event_id)?;
|
||||
|
||||
for instance in instances {
|
||||
res.push_str(&format!("Einheit:, {}\n", sanitize(instance.name)));
|
||||
if let Some(billing_rate_id) = instance.billing_rate_id {
|
||||
let billing_rate = get_billing_rate(settings, billing_rate_id)?;
|
||||
|
||||
res.push_str(&format!("Abrechnungssatz:, {}, {}, Pauschale:, {}, €/Stunde:, {}\n", sanitize(billing_rate.name), sanitize(billing_rate.description.unwrap_or(String::from(""))), sanitize(format!("{} €", billing_rate.lump_sum)), sanitize(format!("{} €", billing_rate.payment_per_hour))));
|
||||
}
|
||||
|
||||
res.push_str(&format!("{}, {}, {}, {}, {}, {}, {}, {}, {}\n", String::from("Personalnummer"), String::from("Vorname"), String::from("Nachname"), String::from("Von"), String::from("Bis"), String::from("Stunden"), String::from("Pauschale"), String::from("Stundengeld"), String::from("Gesamt")));
|
||||
|
||||
|
||||
let position_instances = get_position_instances(settings, instance.instance_id)?;
|
||||
for position_instance in position_instances {
|
||||
if let Some(personnel) = crate::database::controller::billing::personnel_billing::read(settings, position_instance.position_instance_id)? {
|
||||
match get_member_by_uuid(personnel.member_id, settings) {
|
||||
Some(member) => {
|
||||
let begin = match position_instance.real_start_time {
|
||||
Some(start) => utc_to_local_user_time(settings, None, start),
|
||||
None => return Err(CSVGeneratorError::Generator(CSVGeneratorErrorKind::MissingTimes))
|
||||
};
|
||||
let end = match position_instance.real_end_time {
|
||||
Some(end) => utc_to_local_user_time(settings, None, end),
|
||||
None => return Err(CSVGeneratorError::Generator(CSVGeneratorErrorKind::MissingTimes))
|
||||
};
|
||||
|
||||
|
||||
res.push_str(&format!("{}, {}, {}, {}, {}, {}, {}, {}, {}\n", sanitize(member.personnel_number.unwrap_or(0).to_string()), sanitize(member.firstname), sanitize(member.lastname), sanitize(begin), sanitize(end), sanitize(personnel.fulfilled_time.to_string()), sanitize(personnel.money_from_lump_sum.to_string()), sanitize(personnel.money_for_time.to_string()), sanitize(personnel.total_money.to_string())));
|
||||
}
|
||||
None => {
|
||||
return Err(CSVGeneratorError::Generator(CSVGeneratorErrorKind::MissingMember));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
res.push_str("\n");
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn sanitize(mut input: String) -> String {
|
||||
input = input.replace("\"", "\"\"") //escape double quotes by another double quote
|
||||
.replace("\r", "") //Remove carriage returns
|
||||
.replace("\n", "") //Remove new lines
|
||||
.replace("\t", ""); //Remove tabs
|
||||
if input.starts_with("@") || input.starts_with("=") || input.starts_with("+") || input.starts_with("-") { //Add single quote if input starts with @ = + or -
|
||||
input = format!("\'{}", input);
|
||||
}
|
||||
|
||||
format!("\"{}\"", input)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::modules::event_billing::generate_billing_csv::sanitize;
|
||||
|
||||
#[test]
|
||||
fn csv_injection_test1() {
|
||||
assert_eq!(sanitize(String::from("Tes\"t123")), String::from("\"Tes\"\"t123\""))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn csv_injection_test2() {
|
||||
assert_eq!(sanitize(String::from("=1+2\";=1+2")), String::from("\"'=1+2\"\";=1+2\""))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn csv_injection_test3() {
|
||||
assert_eq!(sanitize(String::from("=SUM(A1, A2)")), String::from("\"'=SUM(A1, A2)\""))
|
||||
}
|
||||
}
|
|
@ -2,4 +2,5 @@ pub mod event;
|
|||
pub mod close_event;
|
||||
pub mod edit_times;
|
||||
pub mod approve;
|
||||
pub mod edit_personnel_billing;
|
||||
pub mod edit_personnel_billing;
|
||||
pub mod generate_billing_csv;
|
|
@ -45,6 +45,9 @@ pub fn edit_event(cookie: SessionCookie, _settings: &State<Settings>, id: String
|
|||
},
|
||||
Script {
|
||||
path: "/js/em_edit_event.js".to_string(),
|
||||
},
|
||||
Script {
|
||||
path: "/js/search2.js".to_string(),
|
||||
}],
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue