+
}
diff --git a/src/index.js b/src/index.js
index 4b4dec6..8692561 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,13 +1,9 @@
import React from 'react';
-import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import './util/i18n'
+import { createRoot } from 'react-dom/client';
-ReactDOM.render(
-
-
- ,
- document.getElementById('root')
-);
-
+const container = document.getElementById('root');
+const root = createRoot(container);
+root.render(
);
diff --git a/src/scss/style.scss b/src/scss/style.scss
index 5a55731..2a90f05 100644
--- a/src/scss/style.scss
+++ b/src/scss/style.scss
@@ -1 +1,3 @@
-@import "@coreui/coreui/scss/coreui";
\ No newline at end of file
+@import "@coreui/coreui/scss/coreui";
+
+$enable-shadows: true;
\ No newline at end of file
diff --git a/src/store.js b/src/store.js
index 7350ff6..a1f6850 100644
--- a/src/store.js
+++ b/src/store.js
@@ -1,15 +1,5 @@
-import { createStore } from 'redux';
+import { configureStore } from '@reduxjs/toolkit'
-const initialState = {};
-
-const changeState = (state = initialState, { type, ...rest }) => {
- switch (type) {
- case 'set':
- return { ...state, ...rest };
- default:
- return state;
- }
-};
-
-const store = createStore(changeState);
-export default store;
\ No newline at end of file
+export default configureStore({
+ reducer: {},
+})
\ No newline at end of file
diff --git a/src/util/bill-datatypes.js b/src/util/bill-datatypes.js
index e394e7a..703d9d3 100644
--- a/src/util/bill-datatypes.js
+++ b/src/util/bill-datatypes.js
@@ -8,6 +8,7 @@ export class BillContent {
billNumber /*: string*/;
dateMs/*: number*/;
cancellation/*: boolean*/;
+ companyName/*: string*/;
get date() /*: moment.Moment*/{
return moment(this.dateMs);
@@ -97,3 +98,17 @@ export class R1TrustedSupplier {
}
}
}
+
+export class CompanyInfo {
+ shopName /*: string */;
+ companyName /*: string */;
+ certId /*: string */;
+ uid /*: string */;
+
+ constructor(company) {
+ this.shopName = company.shopName;
+ this.companyName = company.companyName;
+ this.certId = company.certId;
+ this.uid = company.uid;
+ }
+}
diff --git a/src/util/company-matcher.js b/src/util/company-matcher.js
index 688ebb3..00dabd7 100644
--- a/src/util/company-matcher.js
+++ b/src/util/company-matcher.js
@@ -1,16 +1,6 @@
-import companyMappings from './data/companyMapping.json';
+import ApiClient from './qrBackendClient';
-const uidMapping = companyMappings.uidMap;
-const serialMapping = companyMappings.serialMap
-export function matchCompanyByCertSerial(certSerial /*: string*/){
-
- const uidRegExp = new RegExp("^U:ATU\\d{8}-\\d+$","i");
-
- if (uidRegExp.test(certSerial)) {
- const uid = certSerial.slice(2,13);
- return uidMapping[uid];
- }
-
- return serialMapping[certSerial];
+export async function matchCompanyByCertSerial(certSerial /*: string*/){
+ return ApiClient.matchCompanyByQrCertSerial(certSerial).then(data => {return data.companyName});
}
\ No newline at end of file
diff --git a/src/util/config.js b/src/util/config.js
new file mode 100644
index 0000000..37d3873
--- /dev/null
+++ b/src/util/config.js
@@ -0,0 +1,8 @@
+const config = {
+ "api": {
+ "url": "http://localhost:8080/api",
+ "active": false
+ }
+}
+
+export default config;
\ No newline at end of file
diff --git a/src/util/data/companyMapping.json b/src/util/data/companyMapping.json
deleted file mode 100644
index 988b4ca..0000000
--- a/src/util/data/companyMapping.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "uidMap":{
- "ATU19417101":"Media Saturn",
- "ATU24963706":"Hofer KG",
- "ATU42620008":"McDonald's, Eckwolf GmbH",
- "ATU36975500":"McDonald's Franchise GmbH",
- "ATU59193205":"Rewe International"
- },
- "serialMap":{
- "761EF806":"Leberkas-Pepi",
- "4355E3F1":"Leberkas-Pepi",
- "01481d93b9597c":"Lidl",
- "2b7da6b409d5":"Hornbach",
- "1b017d82":"Müller Handels GmbH",
- "1c7b398bfdab4":"Le Crobag Österreich",
- "20c09399862f6ae3":"Haus des Meeres Wien",
- "71d5f74c":"Ebi Vienna",
- "2A38C2E5":"Weltmuseum Wien",
- "54149bce":"Pizza Favori GmbH",
- "4e73db60":"Kleider Bauer",
- "7ec556d4":"Valora Retail Austria",
- "209C31AA":"SSP Österreich GmbH",
- "1eda56d2":"OBI GmbH",
- "208D115D":"OMV Downstream GmbH"
- }
-}
\ No newline at end of file
diff --git a/src/util/qrBackendClient.js b/src/util/qrBackendClient.js
new file mode 100644
index 0000000..548b9ab
--- /dev/null
+++ b/src/util/qrBackendClient.js
@@ -0,0 +1,55 @@
+import {CompanyInfo} from './bill-datatypes';
+import config from './config';
+
+class BackendClient {
+ constructor(apiUrl /*: string*/, active /*: boolean*/ = true) {
+ this.active = active;
+ if (!apiUrl.endsWith('/')) {
+ apiUrl += '/';
+ }
+ this.apiURL = apiUrl;
+ this.companyEndpoint = this.apiURL + "company/";
+ this.healthEndpoint = this.apiURL + "status/health";
+ }
+
+ async matchCompanyByQrCertSerial(certSerial /*: string*/) /*: CompanyInfo*/ {
+ if (this.active === false) {
+ return null;
+ }
+ try {
+ const response = await fetch(this.companyEndpoint + certSerial);
+ return await response.json().then(data => {return new CompanyInfo(data)});
+ } catch (error) {
+ console.debug('Unable to get company info:', error);
+ return null;
+ }
+ }
+
+ isActive() {
+ return this.active;
+ }
+}
+
+class NoOpClient {
+ async matchCompanyByQrCertSerial(certSerial /*: string*/) /*: CompanyInfo*/ {
+ return null;
+ }
+
+ isActive() {
+ return false;
+ }
+}
+
+function getBackendClient() {
+ if (config.api.active) {
+ return new BackendClient(config.api.url);
+
+ } else {
+ console.debug('Backend deativated. Using no-op client.');
+ return new NoOpClient();
+ }
+}
+
+const ApiClient = getBackendClient();
+
+export default ApiClient;
\ No newline at end of file
diff --git a/src/util/storage.js b/src/util/storage.js
index 73d0e42..28c5719 100644
--- a/src/util/storage.js
+++ b/src/util/storage.js
@@ -1,5 +1,6 @@
import Dexie from 'dexie';
import { Amount, R1BillContent, R1TrustedSupplier } from './bill-datatypes';
+import { matchCompanyByCertSerial } from './company-matcher';
const db = new Dexie('qrDatabase');
@@ -10,8 +11,29 @@ db.version(13).stores({
db.r1Bills.mapToClass(R1BillContent);
export async function saveR1Bill(r1Bill){
+ let thisBill = await db.r1Bills
+ .where('billNumber')
+ .equals(r1Bill.billNumber)
+ .first();
+ if (thisBill) {
+ return thisBill.id;
+ }
+
let r1BillMapped = mapR1BillForDb(r1Bill);
- return await db.r1Bills.add(r1BillMapped);
+
+ return db.r1Bills.add(r1BillMapped).then( billId => {
+ if (!r1BillMapped.companyName) {
+ r1BillMapped.id = billId;
+ matchCompanyByCertSerial(r1BillMapped.certSerialR1)
+ .then(companyName => {
+ if (companyName !== null) {
+ r1BillMapped.companyName = companyName;
+ db.r1Bills.put(r1BillMapped);
+ }
+ });
+ }
+ return billId;
+ });
}
export async function readR1Bills(){