Selaa lähdekoodia

[Main] Minimal working version created

Slava Barinov 5 vuotta sitten
vanhempi
commit
56a7fa8e77
4 muutettua tiedostoa jossa 76 lisäystä ja 12 poistoa
  1. 1 1
      Cargo.lock
  2. 1 1
      Cargo.toml
  3. 60 6
      src/main.rs
  4. 14 4
      src/receipt.rs

+ 1 - 1
Cargo.lock

@@ -61,7 +61,7 @@ dependencies = [
 
 [[package]]
 name = "qif_generator"
-version = "0.1.2"
+version = "0.1.3"
 dependencies = [
  "chrono",
 ]

+ 1 - 1
Cargo.toml

@@ -9,5 +9,5 @@ edition = "2018"
 [dependencies]
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
-qif_generator = "0.1.0"
+qif_generator = "0.1.3"
 chrono = "0.4"

+ 60 - 6
src/main.rs

@@ -1,9 +1,16 @@
+use chrono::{Date, Utc};
+use qif_generator::{
+    account::{Account, AccountType},
+    split::Split,
+    transaction::Transaction,
+};
 use std::env;
 use std::fs;
 
+mod qif;
 mod receipt;
 
-fn read_receipt(f: &str) -> Vec<receipt::Item> {
+fn read_receipt(f: &str) -> receipt::Receipt {
     let json = fs::read_to_string(f).expect("Can't read file");
     receipt::parse_receipt(&json)
 }
@@ -19,18 +26,65 @@ mod tests {
         p.push("tests/resources/test.json");
         let full_path = p.to_string_lossy();
 
-        let result = read_receipt(&full_path);
+        let result = read_receipt(&full_path).items;
         assert_eq!(result[0].name, "ХРЕН РУССКИЙ 170Г");
         assert_eq!(result[0].sum, 5549);
     }
 }
 
+fn gen_splits(items: &[receipt::Item]) -> Vec<Split> {
+    let mut result: Vec<Split> = Vec::new();
+    for i in items.iter() {
+        let t = Split::new()
+            .memo(i.name.as_str())
+            .amount(qif::price_convert(i.sum))
+            .build();
+
+        result.push(t);
+    }
+    result
+}
+
+fn gen_trans<'a>(
+    acc: &'a Account,
+    date: Date<Utc>,
+    sum: i64,
+    splits: &'a [Split],
+) -> Result<Transaction<'a>, String> {
+    let t = Transaction::new(acc)
+        .date(date)
+        .memo("New")
+        .with_splits(splits)
+        .build();
+
+    match t {
+        Ok(t) => {
+            if (t.sum() - qif::price_convert(sum)).abs() < 0.005 {
+                Ok(t)
+            } else {
+                Err(format!(
+                    "Total sum is wrong. Expected: {} Got: {}",
+                    qif::price_convert(sum),
+                    t.sum()
+                ))
+            }
+        }
+        Err(e) => Err(e),
+    }
+}
+
 #[cfg(not(tarpaulin_include))]
 fn main() {
     let args: Vec<String> = env::args().collect();
     let filename = &args[1];
-    let items = read_receipt(filename);
-    for i in items.iter() {
-        println!("{}", i.to_string());
-    }
+    let receipt = read_receipt(filename);
+    let splits = gen_splits(&receipt.items);
+    let acc = Account::new()
+        .name("Wallet")
+        .account_type(AccountType::Cash)
+        .build();
+
+    let t = gen_trans(&acc, receipt.date(), receipt.total_sum(), &splits).unwrap();
+    print!("{}", acc.to_string());
+    println!("{}", t.to_string());
 }

+ 14 - 4
src/receipt.rs

@@ -17,11 +17,21 @@ impl fmt::Display for Item {
 #[allow(dead_code)]
 #[allow(non_snake_case)]
 #[derive(Deserialize, Debug)]
-struct Receipt {
+pub struct Receipt {
     totalSum: i64,
     #[serde(with = "custom_date_format")]
     dateTime: Date<Utc>,
-    items: Vec<Item>,
+    pub items: Vec<Item>,
+}
+
+impl Receipt {
+    pub fn total_sum(self) -> i64 {
+        self.totalSum
+    }
+
+    pub fn date(&self) -> Date<Utc> {
+        self.dateTime
+    }
 }
 
 mod custom_date_format {
@@ -59,9 +69,9 @@ struct Input {
     document: Document,
 }
 
-pub fn parse_receipt(line: &str) -> Vec<Item> {
+pub fn parse_receipt(line: &str) -> Receipt {
     let result: Input = serde_json::from_str(&line).unwrap();
-    result.document.receipt.items
+    result.document.receipt
 }
 
 #[cfg(test)]