Kaynağa Gözat

[Receipt] Supported new receipt format

Slava Barinov 4 yıl önce
ebeveyn
işleme
3aa8b3396a
3 değiştirilmiş dosya ile 227 ekleme ve 295 silme
  1. 8 8
      src/main.rs
  2. 88 37
      src/receipt.rs
  3. 131 250
      tests/resources/test.json

+ 8 - 8
src/main.rs

@@ -20,9 +20,9 @@ mod import;
 mod receipt;
 mod ui;
 
-fn read_receipt(f: &str) -> receipt::Receipt {
+fn read_file(f: &str) -> receipt::Purchase {
     let json = fs::read_to_string(f).expect("Can't read file");
-    receipt::parse_receipt(&json)
+    receipt::parse_purchase(&json)
 }
 
 #[cfg(test)]
@@ -35,9 +35,9 @@ mod tests {
         p.push("tests/resources/test.json");
         let full_path = p.to_string_lossy();
 
-        let result = read_receipt(&full_path).items;
-        assert_eq!(result[0].name, "ХРЕН РУССКИЙ 170Г");
-        assert_eq!(result[0].sum, 5549);
+        let result = read_file(&full_path).items;
+        assert_eq!(result[0].name, "СИДР 0.5 MAGNERS APP");
+        assert_eq!(result[0].sum, 17713);
     }
 }
 
@@ -129,14 +129,14 @@ fn main() {
         db.set("accounts", &accounts).unwrap();
     }
 
-    let receipt = read_receipt(&args.filename);
-    let splits = gen_splits(&receipt.items, &mut catmap);
+    let purchase = read_file(&args.filename);
+    let splits = gen_splits(&purchase.items, &mut catmap);
     let acc = Account::new()
         .name("Wallet")
         .account_type(AccountType::Cash)
         .build();
 
-    let t = gen_trans(&acc, receipt.date(), receipt.total_sum(), &splits).unwrap();
+    let t = gen_trans(&acc, purchase.date(), purchase.total_sum(), &splits).unwrap();
     print!("{}", acc.to_string());
     println!("{}", t.to_string());
 

+ 88 - 37
src/receipt.rs

@@ -2,7 +2,23 @@ use chrono::{Date, Utc};
 use serde::Deserialize;
 use std::fmt;
 
-#[derive(Deserialize, Debug)]
+pub struct Purchase {
+    sum: i64,
+    date: Date<Utc>,
+    pub items: Vec<Item>,
+}
+
+impl Purchase {
+    pub fn total_sum(self) -> i64 {
+        self.sum
+    }
+
+    pub fn date(&self) -> Date<Utc> {
+        self.date
+    }
+}
+
+#[derive(Deserialize, Debug, Clone)]
 pub struct Item {
     pub name: String,
     pub sum: i64,
@@ -16,22 +32,30 @@ impl fmt::Display for Item {
 
 #[allow(dead_code)]
 #[allow(non_snake_case)]
-#[derive(Deserialize, Debug)]
-pub struct Receipt {
+#[derive(Deserialize, Debug, Clone)]
+struct Receipt {
     totalSum: i64,
-    #[serde(with = "custom_date_format")]
-    dateTime: Date<Utc>,
     pub items: Vec<Item>,
 }
 
-impl Receipt {
-    pub fn total_sum(self) -> i64 {
-        self.totalSum
-    }
+#[allow(dead_code)]
+#[derive(Deserialize)]
+struct Document {
+    receipt: Receipt,
+}
 
-    pub fn date(&self) -> Date<Utc> {
-        self.dateTime
-    }
+#[allow(dead_code)]
+#[derive(Deserialize)]
+struct Ticket {
+    document: Document,
+}
+
+#[allow(dead_code)]
+#[derive(Deserialize)]
+struct Query {
+    sum: i64,
+    #[serde(with = "custom_date_format")]
+    date: Date<Utc>,
 }
 
 mod custom_date_format {
@@ -39,7 +63,7 @@ mod custom_date_format {
     use serde::{self, Deserialize, Deserializer};
 
     /// The format seems alike to RFC3339 but is not compliant
-    const FORMAT: &str = "%Y-%m-%dT%H:%M:%S";
+    const FORMAT: &str = "%Y-%m-%dT%H:%M";
 
     /// Custom deserializer for format in our json
     pub fn deserialize<'de, D>(deserializer: D) -> Result<Date<Utc>, D::Error>
@@ -57,21 +81,21 @@ mod custom_date_format {
     }
 }
 
-#[allow(dead_code)]
-#[derive(Deserialize)]
-struct Document {
-    receipt: Receipt,
-}
-
 #[allow(dead_code)]
 #[derive(Deserialize)]
 struct Input {
-    document: Document,
+    query: Query,
+    ticket: Ticket,
 }
 
-pub fn parse_receipt(line: &str) -> Receipt {
-    let result: Input = serde_json::from_str(&line).unwrap();
-    result.document.receipt
+pub fn parse_purchase(line: &str) -> Purchase {
+    // TODO: Check if several receipts are possible
+    let receipt: Vec<Input> = serde_json::from_str(&line).unwrap();
+    Purchase {
+        sum: receipt[0].query.sum,
+        date: receipt[0].query.date,
+        items: receipt[0].ticket.document.receipt.items.clone(),
+    }
 }
 
 #[cfg(test)]
@@ -100,6 +124,28 @@ mod receipt {
         assert_eq!(testit.sum, 5549);
     }
 
+    #[test]
+    fn query() {
+        let line = String::from(
+            r#"
+{
+    "date": "2021-03-24T20:02",
+    "documentId": 28230,
+    "fsId": "9282440300829284",
+    "fiscalSign": "1706439950",
+    "operationType": 1,
+    "sum": 267800
+}
+"#,
+        );
+
+        let testit: Query = serde_json::from_str(&line).unwrap();
+        assert_eq!(testit.sum, 267800);
+        assert_eq!(testit.date.day(), 24);
+        assert_eq!(testit.date.month(), 3);
+        assert_eq!(testit.date.year(), 2021);
+    }
+
     #[test]
     fn receipt() {
         let line = String::from(
@@ -127,8 +173,7 @@ mod receipt {
 	    "name" : "СОУС ОСТР.380Г КИНТО",
 	    "sum" : 20599
         }
-    ],
-    "dateTime" : "2020-06-19T17:12:00"
+    ]
 }
 "#,
         );
@@ -138,9 +183,6 @@ mod receipt {
         assert_eq!(testit.items.len(), 2);
         assert_eq!(testit.items[0].sum, 5549);
         assert_eq!(testit.items[1].sum, 20599);
-        assert_eq!(testit.dateTime.day(), 19);
-        assert_eq!(testit.dateTime.month(), 6);
-        assert_eq!(testit.dateTime.year(), 2020);
     }
 
     #[test]
@@ -148,6 +190,15 @@ mod receipt {
         let line = String::from(
             r#"
 {
+"query": {
+      "date": "2021-03-24T20:02",
+      "documentId": 28230,
+      "fsId": "9282440300829284",
+      "fiscalSign": "1706439950",
+      "operationType": 1,
+      "sum": 267800
+    },
+"ticket": {
   "document" : {
     "receipt" : {
       "totalSum" : 548702,
@@ -172,22 +223,22 @@ mod receipt {
           "name" : "СОУС ОСТР.380Г КИНТО",
           "sum" : 20599
         }
-      ],
-    "dateTime" : "2020-06-19T17:12:00"
+      ]
     }
   }
 }
+}
 "#,
         );
 
         let testit: Input = serde_json::from_str(&line).unwrap();
-        assert_eq!(testit.document.receipt.totalSum, 548702);
-        assert_eq!(testit.document.receipt.items.len(), 2);
-        assert_eq!(testit.document.receipt.items[0].sum, 5549);
-        assert_eq!(testit.document.receipt.items[1].sum, 20599);
-        assert_eq!(testit.document.receipt.dateTime.day(), 19);
-        assert_eq!(testit.document.receipt.dateTime.month(), 6);
-        assert_eq!(testit.document.receipt.dateTime.year(), 2020);
+        assert_eq!(testit.ticket.document.receipt.totalSum, 548702);
+        assert_eq!(testit.ticket.document.receipt.items.len(), 2);
+        assert_eq!(testit.ticket.document.receipt.items[0].sum, 5549);
+        assert_eq!(testit.ticket.document.receipt.items[1].sum, 20599);
+        assert_eq!(testit.query.date.day(), 24);
+        assert_eq!(testit.query.date.month(), 3);
+        assert_eq!(testit.query.date.year(), 2021);
     }
 
     #[test]

Dosya farkı çok büyük olduğundan ihmal edildi
+ 131 - 250
tests/resources/test.json


Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor