diff --git a/android/app/build.gradle b/android/app/build.gradle
index 6dd7daa..b57e3a6 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -177,6 +177,8 @@ android {
}
dependencies {
+ compile project(':react-native-nfc-manager')
+ compile project(':react-native-key-event')
compile project(':react-native-localization')
compile project(':react-native-background-job')
compile project(':react-native-bluetooth-status')
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 8babdb9..58ce102 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -9,7 +9,8 @@
-
+
+
+ android:screenOrientation="landscape"
+ android:launchMode="singleTask">
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/java/com/tailpos/MainActivity.java b/android/app/src/main/java/com/tailpos/MainActivity.java
index 3489891..c2d3831 100644
--- a/android/app/src/main/java/com/tailpos/MainActivity.java
+++ b/android/app/src/main/java/com/tailpos/MainActivity.java
@@ -1,7 +1,8 @@
package com.tailpos;
import android.os.Bundle;
-
+import android.view.KeyEvent; // <--- import
+import net.kangyufei.KeyEventModule; // <--- import
import org.devio.rn.splashscreen.SplashScreen;
import com.facebook.react.ReactActivity;
@@ -22,4 +23,20 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
+ @Override // <--- Add this method if you want to react to keyDown
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+
+ KeyEventModule.getInstance().onKeyDownEvent(keyCode, event);
+ super.onKeyDown(keyCode, event);
+ return true;
+ }
+
+ @Override // <--- Add this method if you want to react to keyUp
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ KeyEventModule.getInstance().onKeyUpEvent(keyCode, event);
+
+ super.onKeyUp(keyCode, event);
+ return true;
+ }
+
}
diff --git a/android/app/src/main/java/com/tailpos/MainApplication.java b/android/app/src/main/java/com/tailpos/MainApplication.java
index 9e07ab7..0826b6c 100644
--- a/android/app/src/main/java/com/tailpos/MainApplication.java
+++ b/android/app/src/main/java/com/tailpos/MainApplication.java
@@ -4,6 +4,8 @@
import com.solinor.bluetoothstatus.RNBluetoothManagerPackage;
import com.facebook.react.ReactApplication;
+import community.revteltech.nfc.NfcManagerPackage;
+import net.kangyufei.KeyEventPackage;
import com.babisoft.ReactNativeLocalization.ReactNativeLocalizationPackage;
import com.pilloxa.backgroundjob.BackgroundJobPackage;
import com.learnium.RNDeviceInfo.RNDeviceInfo;
@@ -37,6 +39,8 @@ protected List getPackages() {
return Arrays.asList(
new RNBluetoothManagerPackage(),
new MainReactPackage(),
+ new NfcManagerPackage(),
+ new KeyEventPackage(),
new ReactNativeLocalizationPackage(),
new BackgroundJobPackage(),
new RNDeviceInfo(),
diff --git a/android/app/src/main/res/xml/nfc_tech_filter.xml b/android/app/src/main/res/xml/nfc_tech_filter.xml
new file mode 100644
index 0000000..14c651f
--- /dev/null
+++ b/android/app/src/main/res/xml/nfc_tech_filter.xml
@@ -0,0 +1,29 @@
+
+
+ android.nfc.tech.IsoDep
+
+
+ android.nfc.tech.NfcA
+
+
+ android.nfc.tech.NfcB
+
+
+ android.nfc.tech.NfcF
+
+
+ android.nfc.tech.NfcV
+
+
+ android.nfc.tech.Ndef
+
+
+ android.nfc.tech.NdefFormatable
+
+
+ android.nfc.tech.MifareClassic
+
+
+ android.nfc.tech.MifareUltralight
+
+
\ No newline at end of file
diff --git a/android/settings.gradle b/android/settings.gradle
index 8900f48..d465898 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -1,4 +1,8 @@
rootProject.name = 'TailPOS'
+include ':react-native-nfc-manager'
+project(':react-native-nfc-manager').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-nfc-manager/android')
+include ':react-native-key-event'
+project(':react-native-key-event').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-key-event/android')
include ':react-native-localization'
project(':react-native-localization').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-localization/android')
include ':react-native-background-job'
diff --git a/android/src/main/res/xml/nfc_tech_filter.xml b/android/src/main/res/xml/nfc_tech_filter.xml
new file mode 100644
index 0000000..14c651f
--- /dev/null
+++ b/android/src/main/res/xml/nfc_tech_filter.xml
@@ -0,0 +1,29 @@
+
+
+ android.nfc.tech.IsoDep
+
+
+ android.nfc.tech.NfcA
+
+
+ android.nfc.tech.NfcB
+
+
+ android.nfc.tech.NfcF
+
+
+ android.nfc.tech.NfcV
+
+
+ android.nfc.tech.Ndef
+
+
+ android.nfc.tech.NdefFormatable
+
+
+ android.nfc.tech.MifareClassic
+
+
+ android.nfc.tech.MifareUltralight
+
+
\ No newline at end of file
diff --git a/changes/nfc-manager-build.gradle b/changes/nfc-manager-build.gradle
new file mode 100644
index 0000000..678946f
--- /dev/null
+++ b/changes/nfc-manager-build.gradle
@@ -0,0 +1,42 @@
+def safeExtGet(prop, fallback) {
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
+}
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.5.0'
+ }
+}
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion safeExtGet('compileSdkVersion', 27)
+ buildToolsVersion safeExtGet('buildToolsVersion', '27.0.3')
+
+ defaultConfig {
+ minSdkVersion safeExtGet('minSdkVersion', 16)
+ //noinspection OldTargetApi
+ targetSdkVersion safeExtGet('targetSdkVersion', 27)
+ }
+ lintOptions {
+ abortOnError false
+ }
+}
+
+repositories {
+ mavenCentral()
+ maven {
+ // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
+ url "$rootDir/../node_modules/react-native/android"
+ }
+}
+
+
+dependencies {
+ compile 'com.facebook.react:react-native:+'
+
+}
diff --git a/ios/TailPOS.xcodeproj/project.pbxproj b/ios/TailPOS.xcodeproj/project.pbxproj
index 71ffce9..d83f712 100644
--- a/ios/TailPOS.xcodeproj/project.pbxproj
+++ b/ios/TailPOS.xcodeproj/project.pbxproj
@@ -66,6 +66,7 @@
43FFBF74D0094DD8866DD727 /* libRNBluetoothManager.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 114C3F4566DC4AAFBF009FFF /* libRNBluetoothManager.a */; };
51F0F7BBE5C142D4B8521808 /* libRNBackgroundJob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 030627CBACC14D929C0207BD /* libRNBackgroundJob.a */; };
520D4F11F21A4CEEB05724EB /* libReactNativeLocalization.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A5548395195745ED8AFFDEBB /* libReactNativeLocalization.a */; };
+ 6BEB5BDCB20043EA80E560C6 /* libNfcManager.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D806BF8811F4260B10899D2 /* libNfcManager.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -413,6 +414,8 @@
030627CBACC14D929C0207BD /* libRNBackgroundJob.a */ = {isa = PBXFileReference; name = "libRNBackgroundJob.a"; path = "libRNBackgroundJob.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
D5BF8BC30E324943AB843FEB /* ReactNativeLocalization.xcodeproj */ = {isa = PBXFileReference; name = "ReactNativeLocalization.xcodeproj"; path = "../node_modules/react-native-localization/ReactNativeLocalization.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
A5548395195745ED8AFFDEBB /* libReactNativeLocalization.a */ = {isa = PBXFileReference; name = "libReactNativeLocalization.a"; path = "libReactNativeLocalization.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
+ 2C27E3CBAD07414F89BF7DAE /* NfcManager.xcodeproj */ = {isa = PBXFileReference; name = "NfcManager.xcodeproj"; path = "../node_modules/react-native-nfc-manager/ios/NfcManager.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
+ 2D806BF8811F4260B10899D2 /* libNfcManager.a */ = {isa = PBXFileReference; name = "libNfcManager.a"; path = "libNfcManager.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -455,6 +458,7 @@
43FFBF74D0094DD8866DD727 /* libRNBluetoothManager.a in Frameworks */,
51F0F7BBE5C142D4B8521808 /* libRNBackgroundJob.a in Frameworks */,
520D4F11F21A4CEEB05724EB /* libReactNativeLocalization.a in Frameworks */,
+ 6BEB5BDCB20043EA80E560C6 /* libNfcManager.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -657,6 +661,7 @@
0FC20227933C497CB2330EEF /* RNBluetoothManager.xcodeproj */,
2140AF7DBD7F486D8BC7E6D1 /* RNBackgroundJob.xcodeproj */,
D5BF8BC30E324943AB843FEB /* ReactNativeLocalization.xcodeproj */,
+ 2C27E3CBAD07414F89BF7DAE /* NfcManager.xcodeproj */,
);
name = Libraries;
sourceTree = "";
@@ -1320,6 +1325,7 @@
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TailPOS.app/TailPOS";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1336,6 +1342,7 @@
"$(SRCROOT)/../node_modules/react-native-bluetooth-status/ios",
"$(SRCROOT)/../node_modules/react-native-background-job/ios",
"$(SRCROOT)/../node_modules/react-native-localization",
+ "$(SRCROOT)/../node_modules/react-native-nfc-manager/ios",
);
};
name = Debug;
@@ -1356,6 +1363,7 @@
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TailPOS.app/TailPOS";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1372,6 +1380,7 @@
"$(SRCROOT)/../node_modules/react-native-bluetooth-status/ios",
"$(SRCROOT)/../node_modules/react-native-background-job/ios",
"$(SRCROOT)/../node_modules/react-native-localization",
+ "$(SRCROOT)/../node_modules/react-native-nfc-manager/ios",
);
};
name = Release;
@@ -1406,6 +1415,7 @@
"$(SRCROOT)/../node_modules/react-native-bluetooth-status/ios",
"$(SRCROOT)/../node_modules/react-native-background-job/ios",
"$(SRCROOT)/../node_modules/react-native-localization",
+ "$(SRCROOT)/../node_modules/react-native-nfc-manager/ios",
);
};
name = Debug;
@@ -1439,6 +1449,7 @@
"$(SRCROOT)/../node_modules/react-native-bluetooth-status/ios",
"$(SRCROOT)/../node_modules/react-native-background-job/ios",
"$(SRCROOT)/../node_modules/react-native-localization",
+ "$(SRCROOT)/../node_modules/react-native-nfc-manager/ios",
);
};
name = Release;
@@ -1468,6 +1479,7 @@
TVOS_DEPLOYMENT_TARGET = 9.2;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1484,6 +1496,7 @@
"$(SRCROOT)/../node_modules/react-native-bluetooth-status/ios",
"$(SRCROOT)/../node_modules/react-native-background-job/ios",
"$(SRCROOT)/../node_modules/react-native-localization",
+ "$(SRCROOT)/../node_modules/react-native-nfc-manager/ios",
);
};
name = Debug;
@@ -1513,6 +1526,7 @@
TVOS_DEPLOYMENT_TARGET = 9.2;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1529,6 +1543,7 @@
"$(SRCROOT)/../node_modules/react-native-bluetooth-status/ios",
"$(SRCROOT)/../node_modules/react-native-background-job/ios",
"$(SRCROOT)/../node_modules/react-native-localization",
+ "$(SRCROOT)/../node_modules/react-native-nfc-manager/ios",
);
};
name = Release;
@@ -1557,6 +1572,7 @@
TVOS_DEPLOYMENT_TARGET = 10.1;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1573,6 +1589,7 @@
"$(SRCROOT)/../node_modules/react-native-bluetooth-status/ios",
"$(SRCROOT)/../node_modules/react-native-background-job/ios",
"$(SRCROOT)/../node_modules/react-native-localization",
+ "$(SRCROOT)/../node_modules/react-native-nfc-manager/ios",
);
};
name = Debug;
@@ -1601,6 +1618,7 @@
TVOS_DEPLOYMENT_TARGET = 10.1;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1617,6 +1635,7 @@
"$(SRCROOT)/../node_modules/react-native-bluetooth-status/ios",
"$(SRCROOT)/../node_modules/react-native-background-job/ios",
"$(SRCROOT)/../node_modules/react-native-localization",
+ "$(SRCROOT)/../node_modules/react-native-nfc-manager/ios",
);
};
name = Release;
diff --git a/package-lock.json b/package-lock.json
index 4027ade..5c93029 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4329,8 +4329,7 @@
},
"ansi-regex": {
"version": "2.1.1",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"aproba": {
"version": "1.1.1",
@@ -4395,7 +4394,6 @@
"boom": {
"version": "2.10.1",
"bundled": true,
- "optional": true,
"requires": {
"hoek": "2.x.x"
}
@@ -4538,13 +4536,11 @@
},
"fs.realpath": {
"version": "1.0.0",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"fstream": {
"version": "1.0.11",
"bundled": true,
- "optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
@@ -4595,7 +4591,6 @@
"glob": {
"version": "7.1.2",
"bundled": true,
- "optional": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -4607,8 +4602,7 @@
},
"graceful-fs": {
"version": "4.1.11",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"har-schema": {
"version": "1.0.5",
@@ -4642,8 +4636,7 @@
},
"hoek": {
"version": "2.16.3",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"http-signature": {
"version": "1.1.1",
@@ -4658,7 +4651,6 @@
"inflight": {
"version": "1.0.6",
"bundled": true,
- "optional": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
@@ -4666,8 +4658,7 @@
},
"inherits": {
"version": "2.0.3",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"ini": {
"version": "1.3.4",
@@ -4767,7 +4758,6 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
- "optional": true,
"requires": {
"brace-expansion": "1.1.7"
}
@@ -4780,7 +4770,6 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -4813,8 +4802,8 @@
"bundled": true,
"optional": true,
"requires": {
- "abbrev": "1.1.0",
- "osenv": "0.1.4"
+ "abbrev": "1",
+ "osenv": "^0.1.4"
}
},
"npmlog": {
@@ -4846,7 +4835,6 @@
"once": {
"version": "1.4.0",
"bundled": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -4866,14 +4854,13 @@
"bundled": true,
"optional": true,
"requires": {
- "os-homedir": "1.0.2",
- "os-tmpdir": "1.0.2"
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.0"
}
},
"path-is-absolute": {
"version": "1.0.1",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"performance-now": {
"version": "0.2.0",
@@ -4959,7 +4946,6 @@
"rimraf": {
"version": "2.6.1",
"bundled": true,
- "optional": true,
"requires": {
"glob": "^7.0.5"
}
@@ -5041,7 +5027,6 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -5130,8 +5115,7 @@
},
"wrappy": {
"version": "1.0.2",
- "bundled": true,
- "optional": true
+ "bundled": true
}
}
},
@@ -10082,6 +10066,11 @@
"resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.0.2.tgz",
"integrity": "sha512-5FYNC4kTi/YK86l+r8GQ0xgsSL2tleCQ5Yppu1+ARbnm2qGRmDoJTGSNsWBAWa8FP1ORyhMjxi18IlvSRKaI2g=="
},
+ "react-native-key-event": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/react-native-key-event/-/react-native-key-event-1.0.0.tgz",
+ "integrity": "sha512-bb57EC7q9Y+YUS29Z461neSZlMYKq92x1J1zOd+TdE9Sos3Iqz+c1AwCpng1ob4nR2FUwqI+QAQ3j57rHF5dRQ=="
+ },
"react-native-keyboard-aware-scroll-view": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/react-native-keyboard-aware-scroll-view/-/react-native-keyboard-aware-scroll-view-0.5.0.tgz",
@@ -10156,6 +10145,11 @@
"react-native-animatable": "^1.2.4"
}
},
+ "react-native-nfc-manager": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/react-native-nfc-manager/-/react-native-nfc-manager-1.2.2.tgz",
+ "integrity": "sha512-mOJD2YDpPaG+JzsjB03c+xDsRHr2Vm5CFRr9rtMRt+c/9jdvn/c2+VXCFA5/PJ1GEXdY/vFFOP96Qv5kAau8Mw=="
+ },
"react-native-orientation": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/react-native-orientation/-/react-native-orientation-3.1.3.tgz",
diff --git a/package.json b/package.json
index cdd7fea..026c312 100644
--- a/package.json
+++ b/package.json
@@ -31,7 +31,7 @@
"prettier": "prettier --trailing-comma all --write \"src/**/*.js\"",
"clean": "rm -rf $TMPDIR/react-* && rm -rf node_modules/",
"apk": "cd android && ./gradlew assembleRelease && cd ..",
- "change": "cp changes/localization-build.gradle node_modules/react-native-localization/android/build.gradle && cp changes/deviceinfo-build.gradle node_modules/react-native-device-info/android/build.gradle && cp changes/camera-build.gradle node_modules/react-native-camera/android/build.gradle && cp changes/maps-build.gradle node_modules/react-native-maps/lib/android/build.gradle && cp changes/RCTBluetoothSerialPackage.java node_modules/react-native-bluetooth-serial/android/src/main/java/com/rusel/RCTBluetoothSerial/"
+ "change": "cp changes/nfc-manager-build.gradle node_modules/react-native-nfc-manager/android/build.gradle && cp changes/localization-build.gradle node_modules/react-native-localization/android/build.gradle && cp changes/deviceinfo-build.gradle node_modules/react-native-device-info/android/build.gradle && cp changes/camera-build.gradle node_modules/react-native-camera/android/build.gradle && cp changes/maps-build.gradle node_modules/react-native-maps/lib/android/build.gradle && cp changes/RCTBluetoothSerialPackage.java node_modules/react-native-bluetooth-serial/android/src/main/java/com/rusel/RCTBluetoothSerial/"
},
"jest": {
"preset": "react-native",
@@ -87,9 +87,11 @@
"react-native-datepicker": "^1.7.2",
"react-native-device-info": "^0.21.5",
"react-native-frappe-fetch": "^0.9.1",
+ "react-native-key-event": "^1.0.0",
"react-native-localization": "^2.1.2",
"react-native-maps": "^0.21.0",
"react-native-modal": "^6.0.0",
+ "react-native-nfc-manager": "^1.2.2",
"react-native-orientation": "^3.1.3",
"react-native-searchable-dropdown": "^1.0.4",
"react-native-simple-dialogs": "^0.3.1",
diff --git a/src/boot/background_job.js b/src/boot/background_job.js
new file mode 100644
index 0000000..b6186ed
--- /dev/null
+++ b/src/boot/background_job.js
@@ -0,0 +1,18 @@
+import BackgroundJob from "react-native-background-job";
+import { syncObjectValues } from "../store/PosStore/syncInBackground";
+
+export function background_job_initialization(stores2) {
+ BackgroundJob.cancel({ jobKey: "AutomaticSync" });
+ const backgroundJob = {
+ jobKey: "myJob",
+ job: () => syncObjectValues("sync", stores2, true),
+ };
+ BackgroundJob.register(backgroundJob);
+ let backgroundSchedule = {
+ jobKey: "myJob",
+ period: 360000,
+ allowExecutionInForeground: true,
+ networkType: BackgroundJob.NETWORK_TYPE_UNMETERED,
+ };
+ BackgroundJob.schedule(backgroundSchedule);
+}
diff --git a/src/boot/index.js b/src/boot/index.js
index 9b2d2b9..2f63c75 100644
--- a/src/boot/index.js
+++ b/src/boot/index.js
@@ -38,7 +38,6 @@ export default function() {
}
}
});
-
Promise.all([
favoriteItemPromise,
itemsLength,
@@ -54,14 +53,33 @@ export default function() {
attendantPromise,
rolePromise,
])
+
.then(() => stores.receiptStore.setDefaultCustomer())
.then(() => {
- stores.receiptStore.currentReceipt(
- stores.printerStore.companySettings[0].tax,
- );
+ const { initializeState } = stores.stateStore;
+ initializeState();
+
stores.stateStore.changeCompanyCheckBox(
stores.printerStore.companySettings[0].currencyDisable,
);
+ stores.stateStore.changeOverallTax(
+ stores.printerStore.companySettings[0].enableOverallTax,
+ );
+ stores.stateStore.changeValue(
+ "multipleMop",
+ stores.printerStore.companySettings[0].multipleMop,
+ "Settings",
+ );
+ stores.stateStore.changeValue(
+ "hideMenuBar",
+ stores.printerStore.companySettings[0].hideMenuBar,
+ "Settings",
+ );
+ stores.stateStore.changeValue(
+ "allowRoundOff",
+ stores.printerStore.companySettings[0].allowRoundOff,
+ "Settings",
+ );
});
return app(stores);
diff --git a/src/boot/setup.js b/src/boot/setup.js
index 8c3c2e8..38707d1 100755
--- a/src/boot/setup.js
+++ b/src/boot/setup.js
@@ -2,29 +2,17 @@ import * as React from "react";
import { Provider } from "mobx-react/native";
import { StyleProvider } from "native-base";
import Orientation from "react-native-orientation";
-import BackgroundJob from "react-native-background-job";
import config from "./configureStore";
-import { syncObjectValues } from "../store/PosStore/syncInBackground";
+import { background_job_initialization } from "./background_job";
import App from "../App";
import getTheme from "../theme/components";
import variables from "../theme/variables/platform";
const stores2 = config();
-BackgroundJob.cancel({ jobKey: "AutomaticSync" });
-const backgroundJob = {
- jobKey: "myJob",
- job: () => syncObjectValues("sync", stores2, true),
-};
-BackgroundJob.register(backgroundJob);
-var backgroundSchedule = {
- jobKey: "myJob",
- period: 360000,
- allowExecutionInForeground: true,
- networkType: BackgroundJob.NETWORK_TYPE_UNMETERED,
-};
-BackgroundJob.schedule(backgroundSchedule);
-
+const { initializeState } = stores2.stateStore;
+initializeState();
+background_job_initialization(stores2);
export default function(stores) {
return class Setup extends React.Component {
constructor(props) {
diff --git a/src/container/ListingContainer/index.js b/src/container/ListingContainer/index.js
index 2b4fc94..60457c1 100644
--- a/src/container/ListingContainer/index.js
+++ b/src/container/ListingContainer/index.js
@@ -350,7 +350,6 @@ export default class ListingContainer extends React.Component {
JSON.stringify(index.taxesValue),
"Listing",
);
-
if (this.props.stateStore.listing_state[0].itemMaintenanceStatus) {
this.props.itemStore.setItem(index);
} else {
@@ -431,6 +430,7 @@ export default class ListingContainer extends React.Component {
name: item.name,
sku: item.sku,
price: item.price,
+ tax: item.tax,
soldBy: item.soldBy,
barcode: item.barcode,
description: item.name,
@@ -451,6 +451,7 @@ export default class ListingContainer extends React.Component {
description: item.name,
soldBy: item.soldBy,
price: unformat(item.price),
+ tax: unformat(item.tax),
sku: item.sku,
syncStatus: false,
barcode: item.barcode,
@@ -476,6 +477,7 @@ export default class ListingContainer extends React.Component {
description: item.name,
soldBy: item.soldBy,
price: unformat(item.price),
+ tax: unformat(item.tax),
sku: item.sku,
barcode: item.barcode,
category: item.category,
@@ -500,6 +502,7 @@ export default class ListingContainer extends React.Component {
soldBy: item.soldBy,
price: item.price,
sku: item.sku,
+ tax: item.tax,
barcode: item.barcode,
colorAndShape: item.colorAndShape,
category: item.category,
@@ -526,6 +529,7 @@ export default class ListingContainer extends React.Component {
name: item.name,
soldBy: item.soldBy,
price: item.price,
+ tax: item.tax,
sku: item.sku,
barcode: item.barcode,
colorAndShape: item.colorAndShape,
@@ -545,6 +549,7 @@ export default class ListingContainer extends React.Component {
name: item.name,
soldBy: item.soldBy,
price: unformat(item.price),
+ tax: unformat(item.tax),
sku: item.sku,
barcode: item.barcode,
category: item.category,
@@ -570,6 +575,7 @@ export default class ListingContainer extends React.Component {
name: item.name,
soldBy: item.soldBy,
price: unformat(item.price),
+ tax: unformat(item.tax),
sku: item.sku,
barcode: item.barcode,
category: item.category,
@@ -595,6 +601,7 @@ export default class ListingContainer extends React.Component {
name: item.name,
soldBy: item.soldBy,
price: item.price,
+ tax: item.tax,
sku: item.sku,
barcode: item.barcode,
colorAndShape: item.colorAndShape,
@@ -698,6 +705,7 @@ export default class ListingContainer extends React.Component {
const itemTab = (
0
? this.props.itemStore.queriedRows.slice().sort(sortByName)
@@ -738,6 +746,7 @@ export default class ListingContainer extends React.Component {
const categoryTab = (
{
- let routeName = "";
- if (res.result || res.rowsLength > 0) {
- routeName = "Pin";
- } else {
- routeName = "Login";
- }
- const resetAction = NavigationActions.reset({
- index: 0,
- key: null,
- actions: [NavigationActions.navigate({ routeName })],
- });
- this.props.navigation.dispatch(resetAction);
+ this.props.attendantStore.getData().then(async res => {
+ await this.props.receiptStore.currentReceipt(
+ this.props.printerStore.companySettings[0].tax,
+ );
+ setTimeout(() => {
+ let routeName = "";
+ if (res.result || res.rowsLength > 0) {
+ routeName = "Pin";
+ } else {
+ routeName = "Login";
+ }
+
+ const resetAction = NavigationActions.reset({
+ index: 0,
+ key: null,
+ actions: [NavigationActions.navigate({ routeName })],
+ });
+ this.props.navigation.dispatch(resetAction);
+ }, 3000);
});
}
diff --git a/src/container/LoginContainer/index.js b/src/container/LoginContainer/index.js
index 8689c8c..29e05e2 100644
--- a/src/container/LoginContainer/index.js
+++ b/src/container/LoginContainer/index.js
@@ -81,6 +81,7 @@ export default class LoginContainer extends React.Component {
pin_code: this.state.pin,
role: "Owner",
canLogin: true,
+ canApprove: true,
dateUpdated: Date.now(),
syncStatus: false,
});
diff --git a/src/container/PaymentContainer/controller.js b/src/container/PaymentContainer/controller.js
index e0dee45..1b0ef0b 100644
--- a/src/container/PaymentContainer/controller.js
+++ b/src/container/PaymentContainer/controller.js
@@ -1,3 +1,8 @@
+import {
+ nfc_initialization,
+ // validate_tag_event,
+ unregister_tag_event,
+} from "./nfc_manager_initialization";
export default class PaymentController {
constructor(stateStore) {
this.stateStore = stateStore;
@@ -5,9 +10,32 @@ export default class PaymentController {
modalVisibleChange = modalVisible => {
this.stateStore.changeValue("modalVisible", modalVisible, "Payment");
};
- onChangePayment = payment => {
+ onChangePayment = (payment, props) => {
this.stateStore.changeValue("selected", payment, "Payment");
+ if (
+ payment === "Wallet" &&
+ !props.stateStore.settings_state[0].multipleMop
+ ) {
+ this.stateStore.setPaymentValue(this.stateStore.amount_due);
+ nfc_initialization(props, this.stateStore.deviceId);
+ // validate_tag_event(
+ // {
+ // techTypes: [
+ // "android.nfc.tech.NfcA",
+ // "android.nfc.tech.MifareClassic",
+ // "android.nfc.tech.NdefFormatable",
+ // ],
+ // id: "9AF076DF",
+ // },
+ // props,
+ // this.stateStore.deviceId,
+ // );
+ } else {
+ this.stateStore.setPaymentValue("0");
+ unregister_tag_event();
+ }
};
+
onChangeCustomerName = customerName => {
this.stateStore.changeValue("customerName", customerName, "Payment");
};
diff --git a/src/container/PaymentContainer/index.js b/src/container/PaymentContainer/index.js
index c2bc236..712c930 100644
--- a/src/container/PaymentContainer/index.js
+++ b/src/container/PaymentContainer/index.js
@@ -3,21 +3,19 @@ import { Alert } from "react-native";
import { Toast } from "native-base";
import BluetoothSerial from "react-native-bluetooth-serial";
import { BluetoothStatus } from "react-native-bluetooth-status";
-import TinyPOS from "tiny-esc-pos";
-import { formatNumber } from "accounting-js";
import * as EmailValidator from "email-validator";
import { inject, observer } from "mobx-react/native";
+import { unregister_tag_event } from "./nfc_manager_initialization";
import { currentLanguage } from "../../translations/CurrentLanguage";
import PaymentController from "./controller";
import PaymentScreen from "@screens/Payment";
-
+import { on_pay } from "./on_pay";
import translation from "../../translations/translation";
import LocalizedStrings from "react-native-localization";
+import { check_customers_pin } from "./nfc_manager_initialization";
let strings = new LocalizedStrings(translation);
-const moment = require("moment");
-
@inject(
"itemStore",
"customerStore",
@@ -39,6 +37,20 @@ export default class PaymentContainer extends React.Component {
}
componentWillMount() {
+ this.props.stateStore.resetScannedNfc();
+ this.props.stateStore.set_customers_pin("");
+ this.props.stateStore.is_not_customers_pin();
+ this.props.stateStore.resetPaymentTypes();
+ this.props.stateStore.setMopAmount("0");
+ const { stateStore } = this.props;
+ this.props.stateStore.setBalance(
+ (
+ parseFloat(stateStore.amount_due, 10) -
+ parseFloat(this.get_payment_total(), 10)
+ ).toString(),
+ );
+ this.props.stateStore.changeValue("selected", "Cash", "Payment");
+
this.props.stateStore.setPaymentValue("0");
if (this.props.customerStore.rows.length > 0) {
@@ -124,932 +136,41 @@ export default class PaymentContainer extends React.Component {
}
onValueChange = text => {
+ let payment_state_values = this.props.stateStore.payment_state[0].toJSON();
+ let value =
+ payment_state_values.selected === "Wallet"
+ ? this.props.stateStore.customers_pin_value
+ : this.props.stateStore.payment_value;
+ const { setPaymentValue, set_customers_pin } = this.props.stateStore;
if (text === "Del") {
- const finalValue = this.props.stateStore.payment_value.slice(0, -1);
- this.props.stateStore.setPaymentValue(finalValue);
+ const finalValue = value.slice(0, -1);
+ payment_state_values.selected === "Wallet"
+ ? set_customers_pin(finalValue)
+ : setPaymentValue(finalValue);
} else {
if (text.length > 1) {
- this.props.stateStore.setPaymentValue(text);
+ payment_state_values.selected === "Wallet"
+ ? set_customers_pin(text)
+ : setPaymentValue(text);
} else {
if (this.props.stateStore.payment_value === "0") {
- this.props.stateStore.setPaymentValue(text);
+ payment_state_values.selected === "Wallet"
+ ? set_customers_pin(text)
+ : setPaymentValue(text);
} else {
- this.props.stateStore.setPaymentValue(
- this.props.stateStore.payment_value + text,
- );
+ payment_state_values.selected === "Wallet"
+ ? set_customers_pin(value + text)
+ : setPaymentValue(value + text);
}
}
}
};
- setOrderCompleted() {
- const {
- queueOrigin,
- currentTable,
- setCurrentTable,
- } = this.props.stateStore;
-
- const url = `${queueOrigin}/api/v1/complete_order`;
- const fetchData = {
- method: "POST",
- body: JSON.stringify({
- id: currentTable,
- }),
- };
-
- fetch(url, fetchData)
- .then(res => res.json())
- .then(res => setCurrentTable(-1));
- }
-
onPay = async () => {
- const paymentValue = parseFloat(this.props.stateStore.payment_value);
- const amountDue = parseFloat(this.props.stateStore.amount_due);
-
- if (paymentValue < amountDue) {
- Alert.alert(
- strings.Alert,
- strings.AmountPaidMustBeGreaterThanOrEqualToAmountDue,
- );
- } else if (paymentValue >= amountDue) {
- let receiptNumber = await this.props.receiptStore.numberOfReceipts();
- let receiptNumberLength = receiptNumber.toString().length;
- let finalReceiptNumber = "";
- for (
- let lengthNumber = 0;
- lengthNumber < 15 - receiptNumberLength;
- lengthNumber += 1
- ) {
- finalReceiptNumber = finalReceiptNumber + "0";
- }
- finalReceiptNumber = finalReceiptNumber + receiptNumber.toString();
-
- const receiptCurrent = this.props.receiptStore.defaultReceipt;
- const { deviceId } = this.props.stateStore;
-
- if (deviceId) {
- receiptCurrent.setDeviceId(deviceId);
- }
-
- BluetoothSerial.isConnected().then(res => {
- let totalPurchase = 0.0;
- Alert.alert(
- strings.ReceiptConfirmation, // title
- strings.DoYouWantToPrintReceipt,
- [
- {
- text: strings.No,
- style: "cancel",
- onPress: () => {
- this.setOrderCompleted();
- this.props.shiftStore.defaultShift.addTotalDiscount(
- receiptCurrent.discounts,
- );
- this.props.shiftStore.defaultShift.addTotalTaxes(
- parseFloat(this.props.receiptStore.defaultReceipt.subtotal) *
- (parseFloat(receiptCurrent.taxesValue) / 100),
- );
- this.props.shiftStore.defaultShift.addNumberOfTransaction();
-
- let totalAmountDue = 0.0;
-
- this.props.receiptStore.defaultReceipt.lines.map(val => {
- totalAmountDue =
- parseInt(totalAmountDue, 10) +
- parseInt(val.price.toFixed(2), 10) *
- parseInt(val.qty.toFixed(2), 10);
- if (val.category && val.category !== "No Category") {
- this.props.shiftStore.defaultShift.categoriesAmounts({
- name: val.category,
- total_amount:
- parseInt(val.price.toFixed(2), 10) *
- parseInt(val.qty.toFixed(2), 10),
- });
- }
- if (this.props.stateStore.payment_state[0].selected) {
- this.props.shiftStore.defaultShift.mopAmounts({
- name: this.props.stateStore.payment_state[0].selected,
- total_amount:
- parseInt(val.price.toFixed(2), 10) *
- parseInt(val.qty.toFixed(2), 10),
- });
- }
- });
- if (
- this.props.receiptStore.defaultReceipt.orderType !== "None"
- ) {
- this.props.shiftStore.defaultShift.addOrderType({
- amount: parseFloat(totalAmountDue, 10),
- type: this.props.receiptStore.defaultReceipt.orderType,
- });
- }
- this.props.shiftStore.defaultShift.addTotalSales(
- totalAmountDue,
- );
- this.props.receiptStore.defaultReceipt.lines.map(val => {
- totalPurchase =
- parseFloat(totalPurchase, 10) +
- parseFloat(val.price, 10) * parseFloat(val.qty, 10);
- });
-
- receiptCurrent.completed(
- this.props.attendantStore.defaultAttendant.user_name,
- );
- const { defaultShift } = this.props.shiftStore;
-
- // If shift started and shift hasn't ended
- if (defaultShift.shiftStarted && !defaultShift.shiftEnded) {
- // Set the default receipt
- const { defaultReceipt } = this.props.receiptStore;
-
- // set shift
- defaultReceipt.setShift(defaultShift._id);
-
- const { ending_cash } = defaultShift;
-
- // Set the end cash
- defaultShift.setEndCash(
- ending_cash + defaultReceipt.netTotal,
- );
- }
-
- this.props.receiptStore.defaultReceipt.changeTaxesAmount(
- this.props.receiptStore.defaultReceipt.get_tax_total,
- );
-
- // this.props.receiptStore.defaultReceipt.clear();
- this.props.paymentStore.add({
- receipt: this.props.receiptStore.defaultReceipt._id.toString(),
- date: Date.now(),
- paid: parseInt(this.props.stateStore.payment_value, 10),
- type: this.props.stateStore.payment_state[0].selected,
- dateUpdated: Date.now(),
- syncStatus: false,
- });
- this.props.receiptStore.add(
- this.props.receiptStore.defaultReceipt,
- );
- this.props.receiptStore.setPreviousReceipt(
- this.props.receiptStore.defaultReceipt,
- );
- let discountValueForDisplay = this.props.receiptStore
- .defaultReceipt.discounts;
- let taxesValueForDisplay = this.props.receiptStore
- .defaultReceipt.get_tax_total;
- this.props.receiptStore.newReceipt(
- this.props.printerStore.companySettings[0].tax,
- );
- this.props.receiptStore.setLastScannedBarcode("");
- this.props.receiptStore.unselectReceiptLine();
- this.props.navigation.navigate("Sales", {
- cash: this.props.stateStore.payment_value,
- change: parseFloat(
- parseFloat(this.props.stateStore.payment_value, 10) -
- (parseFloat(totalPurchase, 10) -
- parseFloat(discountValueForDisplay, 10) +
- parseFloat(taxesValueForDisplay, 10)),
- 10,
- ),
- });
- },
- },
- {
- text: strings.Yes,
- onPress: () => {
- this.setOrderCompleted();
- this.props.shiftStore.defaultShift.addTotalDiscount(
- receiptCurrent.discounts,
- );
- this.props.shiftStore.defaultShift.addTotalTaxes(
- parseFloat(this.props.receiptStore.defaultReceipt.subtotal) *
- (parseFloat(receiptCurrent.taxesValue) / 100),
- );
- this.props.shiftStore.defaultShift.addNumberOfTransaction();
-
- // Let me print first
- let totalAmountDue = 0.0;
- let commission_toto = 0.0;
- this.props.receiptStore.defaultReceipt.lines.map(val => {
- // const { defaultShift } = this.props.shiftStore;
- let ComHolder = JSON.parse(val.commission_details);
- ComHolder.map(val2 => {
- commission_toto =
- commission_toto + parseInt(val2.commission_amount, 10);
- });
- // defaultShift.addCommission(
- // parseInt(val.commission_amount, 10),
- // );
- totalAmountDue =
- parseInt(totalAmountDue, 10) +
- parseInt(val.price.toFixed(2), 10) *
- parseInt(val.qty.toFixed(2), 10);
- if (val.category && val.category !== "No Category") {
- this.props.shiftStore.defaultShift.categoriesAmounts({
- name: val.category,
- total_amount:
- parseInt(val.price.toFixed(2), 10) *
- parseInt(val.qty.toFixed(2), 10),
- });
- }
- if (this.props.stateStore.payment_state[0].selected) {
- this.props.shiftStore.defaultShift.mopAmounts({
- name: this.props.stateStore.payment_state[0].selected,
- total_amount:
- parseInt(val.price.toFixed(2), 10) *
- parseInt(val.qty.toFixed(2), 10),
- });
- }
- });
- if (
- this.props.receiptStore.defaultReceipt.orderType !== "None"
- ) {
- this.props.shiftStore.defaultShift.addOrderType({
- amount: parseFloat(totalAmountDue, 10),
- type: this.props.receiptStore.defaultReceipt.orderType,
- });
- }
- this.props.shiftStore.defaultShift.addTotalSales(
- totalAmountDue,
- );
- if (res) {
- const writePromises = [];
-
- writePromises.push(BluetoothSerial.write(TinyPOS.init()));
-
- // Header
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${
- this.props.printerStore.companySettings.length > 0
- ? this.props.printerStore.companySettings[0].name
- ? this.props.printerStore.companySettings[0].name.toString()
- : "Bai Web and Mobile Lab"
- : "Bai Web and Mobile Lab"
- }`,
- { align: "center", size: "doubleheight" },
- true,
- ),
- ),
- );
-
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${
- this.props.printerStore.companySettings.length > 0
- ? this.props.printerStore.companySettings[0].header.toString()
- : ""
- }`,
- { align: "center", size: "normal" },
- true,
- ),
- ),
- );
-
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- "================================",
- { size: "normal" },
- true,
- ),
- ),
- );
-
- // Date
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${moment().format("YYYY/MM/D hh:mm:ss SSS")}`,
- { size: "normal" },
- true,
- ),
- ),
- );
-
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- "================================",
- { size: "normal" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- strings.Cashier +
- `${
- this.props.attendantStore.defaultAttendant.user_name
- }`,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- strings.TransactionNo + `${finalReceiptNumber}`,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- "================================",
- { size: "normal" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- "Mode of payment: " +
- this.props.stateStore.payment_state[0].selected,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- "================================",
- { size: "normal" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- strings.Purchases,
- { align: "center", size: "normal" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- strings.Items +
- " " +
- strings.Amount +
- " ",
- { align: "left", size: "normal", weight: "bold" },
- true,
- ),
- ),
- );
-
- this.props.receiptStore.defaultReceipt.lines.map(val => {
- let finalLines = "";
-
- const name = val.item_name;
-
- if (name.length > 14) {
- let quotientValue = name.length / 14;
- for (
- let quotient = 0;
- quotient < parseInt(quotientValue, 10);
- quotient += 1
- ) {
- let currentCounter = quotient * 14;
- let nameCounter = "";
- for (
- let n = currentCounter;
- n < (quotient + 1) * 14;
- n += 1
- ) {
- nameCounter = nameCounter + name[n];
- }
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${nameCounter}`,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
- }
- if (name.length - parseInt(quotientValue, 10) * 14 > 0) {
- let nameCounterOverflow = "";
- for (
- let m = parseInt(quotientValue, 10) * 14;
- m < name.length;
- m += 1
- ) {
- nameCounterOverflow = nameCounterOverflow + name[m];
- }
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${nameCounterOverflow}`,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
- }
- } else {
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${name}`,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
- }
-
- let priceString = formatNumber(
- parseFloat(val.price, 10),
- ).toString();
- let qtyString = val.qty.toString();
- let amountString = formatNumber(
- parseFloat(val.price, 10) * parseFloat(val.qty, 10),
- ).toString();
-
- for (let ps = 0; ps < 12 - priceString.length; ps += 1) {
- finalLines = finalLines + " ";
- }
-
- finalLines = finalLines + priceString;
-
- for (let qt = 0; qt < 6 - qtyString.length; qt += 1) {
- finalLines = finalLines + " ";
- }
- finalLines = finalLines + qtyString;
-
- for (let as = 0; as < 14 - amountString.length; as += 1) {
- finalLines = finalLines + " ";
- }
-
- finalLines = finalLines + amountString;
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${finalLines}`,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
- totalPurchase =
- parseFloat(totalPurchase, 10) +
- parseFloat(val.price, 10) * parseFloat(val.qty, 10);
- });
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- "================================",
- { align: "left", size: "normal", weight: "bold" },
- true,
- ),
- ),
- );
-
- let subTotal = strings.Subtotal;
- let sub = formatNumber(
- parseFloat(
- this.props.receiptStore.defaultReceipt.subtotal,
- 10,
- ),
- ).toString();
- for (let t = 0; t < 23 - sub.length; t += 1) {
- subTotal = subTotal + " ";
- }
- subTotal = subTotal + sub;
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${subTotal}`,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
- let taxValue = strings.Tax;
- let tax = formatNumber(
- parseFloat(
- this.props.receiptStore.defaultReceipt.get_tax_total,
- 10,
- ),
- ).toString();
- for (let t = 0; t < 29 - tax.length; t += 1) {
- taxValue = taxValue + " ";
- }
- taxValue = taxValue + tax;
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${taxValue}`,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
- let discountValue = strings.Discount;
- let discount = formatNumber(
- parseFloat(
- this.props.receiptStore.defaultReceipt.discounts,
- 10,
- ),
- ).toString();
- for (let d = 0; d < 24 - discount.length; d += 1) {
- discountValue = discountValue + " ";
- }
- discountValue = discountValue + discount;
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${discountValue}`,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
-
- let commissionValue = strings.Commission;
-
- let commission_total = formatNumber(
- parseFloat(commission_toto, 10),
- ).toString();
- for (let d = 0; d < 22 - commission_total.length; d += 1) {
- commissionValue = commissionValue + " ";
- }
- commissionValue = commissionValue + commission_total;
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${commissionValue}`,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
-
- let total = "";
- total = total + strings.TotalAmount;
-
- for (
- let totalLength = 0;
- totalLength <
- 20 -
- formatNumber(parseFloat(totalPurchase, 10)).toString()
- .length;
- totalLength += 1
- ) {
- total = total + " ";
- }
- total =
- total +
- formatNumber(
- parseFloat(totalPurchase, 10) -
- parseFloat(
- this.props.receiptStore.defaultReceipt.discounts,
- 10,
- ) +
- parseFloat(
- this.props.receiptStore.defaultReceipt.get_tax_total,
- 10,
- ),
- ).toString();
-
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${total}`,
- { align: "left", size: "normal", weight: "bold" },
- true,
- ),
- ),
- );
- let cash = strings.Cash;
- for (
- let cashLength = 0;
- cashLength <
- 28 -
- formatNumber(
- parseFloat(this.props.stateStore.payment_value, 10),
- ).toString().length;
- cashLength += 1
- ) {
- cash = cash + " ";
- }
- cash =
- cash +
- formatNumber(
- parseFloat(this.props.stateStore.payment_value, 10),
- ).toString();
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${cash}`,
- { align: "left", size: "normal", weight: "bold" },
- true,
- ),
- ),
- );
- let change = strings.Change;
- let changeValue = formatNumber(
- parseFloat(
- parseFloat(this.props.stateStore.payment_value, 10) -
- (parseFloat(totalPurchase, 10) -
- parseFloat(
- this.props.receiptStore.defaultReceipt.discounts,
- 10,
- ) +
- parseFloat(
- this.props.receiptStore.defaultReceipt
- .get_tax_total,
- 10,
- )),
- 10,
- ),
- ).toString();
- for (
- let changeLength = 0;
- changeLength < 26 - changeValue.length;
- changeLength += 1
- ) {
- change = change + " ";
- }
- change = change + changeValue;
-
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${change}`,
- { align: "left", size: "normal", weight: "bold" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- "================================",
- { size: "normal" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- strings.ThisServesAsYour,
- { align: "center", size: "doubleheight" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- strings.OfficialReceipt + "\n",
- { align: "center", size: "doubleheight" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- `${
- this.props.printerStore.companySettings.length > 0
- ? this.props.printerStore.companySettings[0].footer.toString()
- : ""
- }`,
- { align: "center", size: "normal" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- "\n" +
- strings.POSProvider +
- "Bai Web and Mobile Lab\n" +
- "Insular Life Bldg, Don Apolinar\n" +
- "Velez cor. Oldarico Akut St.,\n" +
- "Cagayan de Oro, 9000,\n" +
- "Misamis Oriental\n" +
- strings.AccredNo +
- strings.DateIssued +
- strings.ValidUntil,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- strings.ThisReceiptShallBeValidFor +
- strings.FiveYearsFromTheDateOf +
- strings.ThePermitToUse,
- { align: "center", size: "normal" },
- true,
- ),
- ),
- );
-
- // Add 3 new lines
- writePromises.push(
- BluetoothSerial.write(TinyPOS.bufferedLine(3)),
- );
-
- // Push drawer
- writePromises.push(
- BluetoothSerial.write(TinyPOS.kickCashDrawer()),
- );
- writePromises.push(
- BluetoothSerial.write(TinyPOS.kickCashDrawer()),
- );
-
- Promise.all(writePromises)
- .then(res2 => {
- receiptCurrent.completed(
- this.props.attendantStore.defaultAttendant.user_name,
- );
-
- this.props.receiptStore.defaultReceipt.changeTaxesAmount(
- this.props.receiptStore.defaultReceipt.get_tax_total,
- );
- // add to row
- this.props.paymentStore.add({
- receipt: this.props.receiptStore.defaultReceipt._id.toString(),
- date: Date.now(),
- paid: parseInt(this.props.stateStore.payment_value, 10),
- type: this.props.stateStore.payment_state[0].selected,
- dateUpdated: Date.now(),
- syncStatus: false,
- });
-
- // Reset payment amount
- // this.setState({
- // modalVisible: false,
- // paymentAmount: 0,
- // });
- this.props.stateStore.changeValue(
- "modalVisible",
- false,
- "Payment",
- );
- this.props.stateStore.changeValue(
- "paymentAmount",
- 0,
- "Payment",
- );
-
- Toast.show({
- text: strings.TransactionCompleted,
- duration: 5000,
- });
- })
- .catch(err => {
- receiptCurrent.completed(
- this.props.attendantStore.defaultAttendant.user_name,
- );
-
- this.props.receiptStore.defaultReceipt.changeTaxesAmount(
- this.props.receiptStore.defaultReceipt.get_tax_total,
- );
-
- // add to row
- this.props.paymentStore.add({
- receipt: this.props.receiptStore.defaultReceipt._id.toString(),
- date: Date.now(),
- paid: parseInt(this.props.stateStore.payment_value, 10),
- type: this.props.stateStore.payment_state[0].selected,
- dateUpdated: Date.now(),
- syncStatus: false,
- });
- // this.setState({
- // modalVisible: false,
- // paymentAmount: 0,
- // });
- this.props.stateStore.changeValue(
- "modalVisible",
- false,
- "Payment",
- );
- this.props.stateStore.changeValue(
- "paymentAmount",
- 0,
- "Payment",
- );
- Toast.show({
- text: err.message + strings.TransactionCompleted,
- buttonText: strings.Okay,
- position: "bottom",
- duration: 5000,
- });
- });
- } else {
- receiptCurrent.completed(
- this.props.attendantStore.defaultAttendant.user_name,
- );
-
- this.props.receiptStore.defaultReceipt.changeTaxesAmount(
- this.props.receiptStore.defaultReceipt.get_tax_total,
- );
-
- // add to row
- this.props.paymentStore.add({
- receipt: this.props.receiptStore.defaultReceipt._id.toString(),
- date: Date.now(),
- paid: parseInt(this.props.stateStore.payment_value, 10),
- type: this.props.stateStore.payment_state[0].selected,
- dateUpdated: Date.now(),
- syncStatus: false,
- });
-
- // this.setState({
- // modalVisible: false,
- // paymentAmount: 0,
- // });
- this.props.stateStore.changeValue(
- "modalVisible",
- false,
- "Payment",
- );
- this.props.stateStore.changeValue(
- "paymentAmount",
- 0,
- "Payment",
- );
- Toast.show({
- text:
- strings.TransactionCompleted[
- strings.UnableToConnectPrinter
- ],
- buttonText: strings.Okay,
- position: "bottom",
- duration: 6000,
- });
- }
-
- const { defaultShift } = this.props.shiftStore;
-
- // If shift started and shift hasn't ended
- if (defaultShift.shiftStarted && !defaultShift.shiftEnded) {
- // Set the default receipt
- const { defaultReceipt } = this.props.receiptStore;
-
- // set shift
- defaultReceipt.setShift(defaultShift._id);
-
- const { ending_cash } = defaultShift;
-
- // Set the end cash
- defaultShift.setEndCash(
- ending_cash + defaultReceipt.netTotal,
- );
- }
-
- // this.props.receiptStore.defaultReceipt.clear();
- this.props.receiptStore.add(
- this.props.receiptStore.defaultReceipt,
- );
- this.props.receiptStore.setPreviousReceipt(
- this.props.receiptStore.defaultReceipt,
- );
- let discountValueForDisplay = this.props.receiptStore
- .defaultReceipt.discounts;
- let taxesValueForDisplay = this.props.receiptStore
- .defaultReceipt.get_tax_total;
- this.props.receiptStore.newReceipt(
- this.props.printerStore.companySettings[0].tax,
- );
- this.props.receiptStore.setLastScannedBarcode("");
- this.props.receiptStore.unselectReceiptLine();
- this.props.navigation.navigate("Sales", {
- cash: this.props.stateStore.payment_value,
- change: parseFloat(
- parseFloat(this.props.stateStore.payment_value, 10) -
- (parseFloat(totalPurchase, 10) -
- parseFloat(discountValueForDisplay, 10) +
- parseFloat(taxesValueForDisplay, 10)),
- 10,
- ),
- });
- },
- },
- ],
- );
- });
- }
+ const { defaultReceipt } = this.props.receiptStore;
+ const { defaultAttendant } = this.props.attendantStore;
+ defaultReceipt.setAttendant(defaultAttendant.user_name);
+ on_pay(this.props);
};
onBack() {
@@ -1057,22 +178,14 @@ export default class PaymentContainer extends React.Component {
}
navigation = () => {
+ this.props.stateStore.setPaymentValue("0");
+ this.props.stateStore.setMopAmount("0");
+ const { stateStore } = this.props;
+ stateStore.resetPaymentTypes();
+ unregister_tag_event();
this.getBluetoothState(true);
this.onBack();
};
- // DEPRECATED
- // onPrinterChange(value) {
- // this.props.stateStore.changeValue("itemSelected", value, "Payment");
- // BluetoothSerial.connect("DC:0D:30:0B:77:B1")
- // .then(res => {
- // this.props.stateStore.changeValue("connection", true, "Payment");
- // })
- // .catch(() => {
- // // this.setState({ connection: false });
- // this.props.stateStore.changeValue("connection", false, "Payment");
- // });
- // }
-
onPrinterPress = () => {
this.props.navigation.navigate("Settings");
};
@@ -1203,13 +316,72 @@ export default class PaymentContainer extends React.Component {
this.props.stateStore.changeValue("customerPhoneNumber", "", "Payment");
this.props.stateStore.changeValue("customerNotes", "", "Payment");
};
-
+ get_payment_total = () => {
+ let payment_data = JSON.parse(this.props.stateStore.payment_types);
+ let total = 0;
+ for (let i = 0; i < payment_data.length; i += 1) {
+ total += parseFloat(payment_data[i].amount, 10);
+ }
+ return total;
+ };
+ addMultipleMop = () => {
+ const { stateStore } = this.props;
+ if (parseFloat(this.props.stateStore.payment_value, 10) > 0) {
+ stateStore.updatePaymentType({
+ type: this.props.stateStore.payment_state[0].selected,
+ amount: parseFloat(this.props.stateStore.payment_value, 10),
+ });
+ stateStore.setMopAmount(this.get_payment_total().toString());
+ stateStore.setBalance(
+ (
+ parseFloat(stateStore.amount_due, 10) -
+ parseFloat(this.get_payment_total(), 10)
+ ).toString(),
+ );
+ stateStore.setPaymentValue("0");
+ } else {
+ Toast.show({
+ text: "Please input amount greater than 0",
+ buttonText: strings.Okay,
+ position: "bottom",
+ duration: 6000,
+ });
+ }
+ };
+ removeMop = () => {
+ const { stateStore } = this.props;
+ stateStore.removePaymentType();
+ stateStore.setMopAmount(this.get_payment_total().toString());
+ stateStore.setBalance(
+ (
+ parseFloat(stateStore.amount_due, 10) -
+ parseFloat(this.get_payment_total(), 10)
+ ).toString(),
+ );
+ };
+ proceedToWalletTransaction = () => {
+ const {
+ scanned_nfc,
+ customers_pin_value,
+ deviceId,
+ } = this.props.stateStore;
+ check_customers_pin(scanned_nfc, customers_pin_value, this.props, deviceId);
+ };
+ clearCustomersPin = () => {
+ const { set_customers_pin } = this.props.stateStore;
+ set_customers_pin("");
+ };
render() {
strings.setLanguage(currentLanguage().companyLanguage);
return (
+ this.controller.onChangePayment(payment, this.props)
+ }
onChangeCustomerName={this.controller.onChangeCustomerName}
onChangeCustomerEmail={this.controller.onChangeCustomerEmail}
onChangeCustomerPhoneNumber={this.onChangeCustomerPhoneNumber}
@@ -1239,6 +414,10 @@ export default class PaymentContainer extends React.Component {
}
useDefaultCustomer={this.props.stateStore.useDefaultCustomer}
isCurrencyDisabled={this.props.stateStore.isCurrencyDisabled}
+ settings_state={this.props.stateStore.settings_state[0]}
+ addMultipleMop={this.addMultipleMop}
+ removeMop={this.removeMop}
+ proceedToWalletTransaction={this.proceedToWalletTransaction}
/>
);
}
diff --git a/src/container/PaymentContainer/nfc_manager_initialization.js b/src/container/PaymentContainer/nfc_manager_initialization.js
new file mode 100644
index 0000000..f8fcc14
--- /dev/null
+++ b/src/container/PaymentContainer/nfc_manager_initialization.js
@@ -0,0 +1,273 @@
+import { Alert } from "react-native";
+import NfcManager from "react-native-nfc-manager";
+import { showToastDanger, showToast } from "../../utils";
+import config from "../../boot/configureStore";
+import { on_pay } from "./on_pay";
+import { NetInfo } from "react-native";
+
+import FrappeFetch from "react-native-frappe-fetch";
+let validUrl = require("valid-url");
+const stores = config();
+
+export function nfc_initialization(props, deviceId) {
+ NfcManager.isSupported().then(result => {
+ if (result) {
+ check_tagged_nfc_card(props, deviceId);
+ } else {
+ showToastDanger("Device does not support NFC");
+ }
+ });
+}
+
+export function check_tagged_nfc_card(props, deviceId) {
+ NfcManager.isEnabled().then(status => {
+ if (status) {
+ register_tag_event(props, deviceId);
+ } else {
+ showToastDanger("NFC is disabled");
+ }
+ });
+}
+
+export function register_tag_event(props, deviceId) {
+ const nfc_props = {
+ invalidateAfterFirstRead: true,
+ isReaderModeEnabled: true,
+ };
+ const message = "Scanning NFC Card";
+ showToast("Please Scan Customer Card Now");
+ NfcManager.registerTagEvent(
+ tag => validate_tag_event(tag, props, deviceId),
+ message,
+ nfc_props,
+ );
+}
+
+export function unregister_tag_event() {
+ NfcManager.unregisterTagEvent();
+}
+
+export function set_attendant(props) {
+ const { defaultReceipt } = props.receiptStore;
+ const { defaultAttendant } = props.attendantStore;
+ defaultReceipt.setAttendant(defaultAttendant.user_name);
+}
+
+export async function validate_tag_event(tag, props, deviceId) {
+ set_attendant(props);
+ check_internet_connection(tag, props, deviceId);
+}
+
+export async function check_internet_connection(tag, props, deviceId) {
+ NetInfo.isConnected.fetch().then(async isConnected => {
+ if (isConnected) {
+ on_check_tag_event(tag, props, deviceId);
+ } else {
+ showToastDanger("No Internet Connection. Please Check");
+ }
+ });
+}
+
+export async function on_check_tag_event(tag, props, deviceId) {
+ let scanned_nfc = JSON.parse(props.stateStore.scanned_nfc);
+ if (!("customer" in scanned_nfc)) {
+ check_customer_tag(tag, props, deviceId);
+ } else if (
+ !("attendant" in scanned_nfc) &&
+ props.stateStore.customers_pin_value
+ ) {
+ check_attendant_tag(tag, props, deviceId);
+ } else if (
+ !("attendant" in scanned_nfc) &&
+ !props.stateStore.customers_pin_value
+ ) {
+ showToastDanger("Please enter customers pin first");
+ }
+}
+export async function check_customers_pin(
+ scanned_nfc,
+ customers_pin,
+ props,
+ deviceId,
+) {
+ if (scanned_nfc) {
+ if (validUrl.isWebUri(returnUrl().url)) {
+ FrappeFetch.createClient(returnUrl())
+ .then(() => {
+ const { Client } = FrappeFetch;
+ return Client.postApi(
+ "tailpos_sync.wallet_sync.check_customers_pin",
+ {
+ wallet_card_number: scanned_nfc,
+ customers_pin: customers_pin,
+ },
+ );
+ })
+ .catch(() => {})
+ .then(response => response.json())
+ .then(responseJson => {
+ if (responseJson.message.failed) {
+ showToastDanger(responseJson.message.message);
+ } else {
+ showToast(responseJson.message.message);
+ props.stateStore.is_customers_pin();
+ }
+ })
+ .catch(() =>
+ showToastDanger(
+ "Please check your credentials in Sync settings and Error Logs in ERPNext",
+ ),
+ );
+ } else {
+ showToastDanger("Invalid URL. Please set valid URL in Sync Settings");
+ }
+ }
+}
+export async function check_attendant_tag(tag, props, deviceId) {
+ if (tag) {
+ if (validUrl.isWebUri(returnUrl().url)) {
+ FrappeFetch.createClient(returnUrl())
+ .then(() => {
+ const { Client } = FrappeFetch;
+ return Client.postApi(
+ "tailpos_sync.wallet_sync.validate_if_attendant_wallet_exists",
+ {
+ wallet_card_number: tag.id,
+ },
+ );
+ })
+ .catch(() => {})
+ .then(response => response.json())
+ .then(responseJson => {
+ if (responseJson.message.failed) {
+ showToastDanger(responseJson.message.message);
+ } else {
+ props.stateStore.updateScannedNfc("attendant", tag.id);
+
+ proceed_to_validate_sync(props, deviceId);
+ }
+ })
+ .catch(() =>
+ showToastDanger(
+ "Please check your credentials in Sync settings and Error Logs in ERPNext",
+ ),
+ );
+ } else {
+ showToastDanger("Invalid URL. Please set valid URL in Sync Settings");
+ }
+ }
+}
+export async function proceed_to_validate_sync(props, deviceId) {
+ Alert.alert(
+ "Confirm Wallet Transaction",
+ "Are you sure you want to proceed wallet transaction?",
+ [
+ { text: "No", style: "cancel" },
+ {
+ text: "Yes",
+ onPress: () => {
+ on_sync_tag_event(props.stateStore.scanned_nfc, props, deviceId);
+ },
+ },
+ ],
+ );
+}
+export async function check_customer_tag(tag, props, deviceId) {
+ if (tag) {
+ const { defaultReceipt } = stores.receiptStore;
+ if (validUrl.isWebUri(returnUrl().url)) {
+ FrappeFetch.createClient(returnUrl())
+ .then(() => {
+ const { Client } = FrappeFetch;
+ return Client.postApi(
+ "tailpos_sync.wallet_sync.validate_if_customer_wallet_exists",
+ {
+ wallet_card_number: tag.id,
+ receipt: json_object(defaultReceipt),
+ },
+ );
+ })
+
+ .catch(() => {})
+ .then(response => response.json())
+ .then(responseJson => {
+ if (responseJson.message.failed) {
+ showToastDanger(responseJson.message.message);
+ } else {
+ props.stateStore.updateScannedNfc("customer", tag.id);
+ showToast(responseJson.message.message);
+ }
+ })
+
+ .catch(() =>
+ showToastDanger(
+ "Please check your credentials in Sync settings and Error Logs in ERPNext",
+ ),
+ );
+ } else {
+ showToastDanger("Invalid URL. Please set valid URL in Sync Settings");
+ }
+ }
+}
+
+export async function on_sync_tag_event(scanned_nfc, props, deviceId) {
+ if (scanned_nfc) {
+ const { defaultReceipt } = stores.receiptStore;
+ if (validUrl.isWebUri(returnUrl().url)) {
+ FrappeFetch.createClient(returnUrl())
+ .then(() => {
+ const { Client } = FrappeFetch;
+ return Client.postApi("tailpos_sync.wallet_sync.validate_wallet", {
+ wallet: scanned_nfc,
+ receipt: json_object(defaultReceipt),
+ device_id: deviceId,
+ });
+ })
+ .catch(() => {})
+ .then(response => response.json())
+ .then(responseJson => {
+ validate_return_from_server(responseJson.message, props);
+ })
+ .catch(() =>
+ showToastDanger(
+ "Please check your credentials in Sync settings and Error Logs in ERPNext",
+ ),
+ );
+ } else {
+ showToastDanger("Invalid URL. Please set valid URL in Sync Settings");
+ }
+ }
+}
+
+export function validate_return_from_server(data, props) {
+ if (data.failed) {
+ showToastDanger(data.message);
+ } else {
+ showToast("Wallet Scanned Successfully");
+
+ stores.navigation = props.navigation;
+ on_pay(stores);
+ }
+}
+export function json_object(obj) {
+ let receipt_json_object = {};
+ Object.keys(obj).forEach(function(key) {
+ if (!(key === "_id")) {
+ receipt_json_object[key] = obj[key];
+ }
+ });
+
+ return receipt_json_object;
+}
+export function returnUrl() {
+ const { url, user_name, password, isHttps } = stores.printerStore.sync[0];
+
+ const protocol = isHttps ? "https://" : "http://";
+ let site_url = protocol + url;
+
+ return {
+ url: site_url.toLowerCase(),
+ username: user_name,
+ password: password,
+ };
+}
diff --git a/src/container/PaymentContainer/on_pay.js b/src/container/PaymentContainer/on_pay.js
new file mode 100644
index 0000000..e9fae32
--- /dev/null
+++ b/src/container/PaymentContainer/on_pay.js
@@ -0,0 +1,900 @@
+import { Alert } from "react-native";
+import TinyPOS from "tiny-esc-pos";
+import { formatNumber } from "accounting-js";
+import BluetoothSerial from "react-native-bluetooth-serial";
+import { Toast } from "native-base";
+import translation from "../../translations/translation";
+import LocalizedStrings from "react-native-localization";
+let strings = new LocalizedStrings(translation);
+const moment = require("moment");
+
+export async function setOrderCompleted(props) {
+ const { queueOrigin, currentTable, setCurrentTable } = props.stateStore;
+
+ const url = `${queueOrigin}/api/v1/complete_order`;
+ const fetchData = {
+ method: "POST",
+ body: JSON.stringify({
+ id: currentTable,
+ }),
+ };
+
+ fetch(url, fetchData)
+ .then(res => res.json())
+ .then(res => setCurrentTable(-1));
+}
+export async function on_pay(props) {
+ const paymentValue = props.stateStore.settings_state[0].multipleMop
+ ? parseFloat(props.stateStore.payment_amount)
+ : parseFloat(props.stateStore.payment_value);
+ const amountDue = parseFloat(props.stateStore.amount_due);
+
+ if (paymentValue < amountDue) {
+ Alert.alert(
+ strings.Alert,
+ strings.AmountPaidMustBeGreaterThanOrEqualToAmountDue,
+ );
+ } else if (paymentValue >= amountDue) {
+ let receiptNumber = await props.receiptStore.numberOfReceipts();
+ let receiptNumberLength = receiptNumber.toString().length;
+ let finalReceiptNumber = "";
+ for (
+ let lengthNumber = 0;
+ lengthNumber < 15 - receiptNumberLength;
+ lengthNumber += 1
+ ) {
+ finalReceiptNumber = finalReceiptNumber + "0";
+ }
+ finalReceiptNumber = finalReceiptNumber + receiptNumber.toString();
+
+ const receiptCurrent = props.receiptStore.defaultReceipt;
+ const { deviceId } = props.stateStore;
+ receiptCurrent.setRoundOff(
+ props.stateStore.settings_state[0].allowRoundOff,
+ );
+ if (deviceId) {
+ receiptCurrent.setDeviceId(deviceId);
+ }
+
+ BluetoothSerial.isConnected().then(res => {
+ let totalPurchase = 0.0;
+ Alert.alert(
+ strings.ReceiptConfirmation, // title
+ strings.DoYouWantToPrintReceipt,
+ [
+ {
+ text: strings.No,
+ style: "cancel",
+ onPress: () => {
+ setOrderCompleted(props);
+ props.shiftStore.defaultShift.addTotalDiscount(
+ receiptCurrent.discounts,
+ );
+ props.shiftStore.defaultShift.addTotalTaxes(
+ parseFloat(props.receiptStore.defaultReceipt.subtotal) *
+ (parseFloat(receiptCurrent.taxesValue) / 100),
+ );
+ props.shiftStore.defaultShift.addNumberOfTransaction();
+
+ let totalAmountDue = 0.0;
+
+ props.receiptStore.defaultReceipt.lines.map(val => {
+ totalAmountDue =
+ parseInt(totalAmountDue, 10) +
+ parseInt(val.price.toFixed(2), 10) *
+ parseInt(val.qty.toFixed(2), 10);
+ if (val.category && val.category !== "No Category") {
+ props.shiftStore.defaultShift.categoriesAmounts({
+ name: val.category,
+ total_amount:
+ parseInt(val.price.toFixed(2), 10) *
+ parseInt(val.qty.toFixed(2), 10),
+ });
+ }
+ if (props.stateStore.payment_state[0].selected) {
+ props.shiftStore.defaultShift.mopAmounts({
+ name: props.stateStore.payment_state[0].selected,
+ total_amount:
+ parseInt(val.price.toFixed(2), 10) *
+ parseInt(val.qty.toFixed(2), 10),
+ });
+ }
+ });
+ if (props.receiptStore.defaultReceipt.orderType !== "None") {
+ props.shiftStore.defaultShift.addOrderType({
+ amount: parseFloat(totalAmountDue, 10),
+ type: props.receiptStore.defaultReceipt.orderType,
+ });
+ }
+ props.shiftStore.defaultShift.addTotalSales(totalAmountDue);
+ props.receiptStore.defaultReceipt.lines.map(val => {
+ totalPurchase =
+ parseFloat(totalPurchase, 10) +
+ parseFloat(val.price, 10) * parseFloat(val.qty, 10);
+ });
+
+ receiptCurrent.completed(
+ props.attendantStore.defaultAttendant.user_name,
+ );
+ const { defaultShift } = props.shiftStore;
+
+ // If shift started and shift hasn't ended
+ if (defaultShift.shiftStarted && !defaultShift.shiftEnded) {
+ // Set the default receipt
+ const { defaultReceipt } = props.receiptStore;
+
+ // set shift
+ defaultReceipt.setShift(defaultShift._id);
+
+ const { ending_cash } = defaultShift;
+
+ // Set the end cash
+ defaultShift.setEndCash(ending_cash + defaultReceipt.netTotal);
+ }
+
+ props.receiptStore.defaultReceipt.changeTaxesAmount(
+ props.stateStore.enableOverallTax
+ ? props.receiptStore.defaultReceipt.get_tax_total
+ : props.receiptStore.defaultReceipt
+ .get_tax_total_based_on_each_item,
+ );
+
+ // props.receiptStore.defaultReceipt.clear();
+ payment_add(props);
+
+ props.receiptStore.add(props.receiptStore.defaultReceipt);
+ props.receiptStore.setPreviousReceipt(
+ props.receiptStore.defaultReceipt,
+ );
+ let discountValueForDisplay =
+ props.receiptStore.defaultReceipt.discounts;
+ let taxesValueForDisplay = props.stateStore.enableOverallTax
+ ? props.receiptStore.defaultReceipt.get_tax_total
+ : props.receiptStore.defaultReceipt
+ .get_tax_total_based_on_each_item;
+ props.receiptStore.newReceipt(
+ props.printerStore.companySettings[0].tax,
+ );
+ props.receiptStore.setLastScannedBarcode("");
+ props.receiptStore.unselectReceiptLine();
+ props.stateStore.changeValue("selected", "Cash", "Payment");
+ change_navigation(
+ props,
+ totalPurchase,
+ discountValueForDisplay,
+ taxesValueForDisplay,
+ );
+ },
+ },
+ {
+ text: strings.Yes,
+ onPress: () => {
+ setOrderCompleted(props);
+ props.shiftStore.defaultShift.addTotalDiscount(
+ receiptCurrent.discounts,
+ );
+ props.shiftStore.defaultShift.addTotalTaxes(
+ parseFloat(props.receiptStore.defaultReceipt.subtotal) *
+ (parseFloat(receiptCurrent.taxesValue) / 100),
+ );
+ props.shiftStore.defaultShift.addNumberOfTransaction();
+
+ // Let me print first
+ let totalAmountDue = 0.0;
+ let commission_toto = 0.0;
+ props.receiptStore.defaultReceipt.lines.map(val => {
+ // const { defaultShift } = props.shiftStore;
+ let ComHolder = JSON.parse(val.commission_details);
+ ComHolder.map(val2 => {
+ commission_toto =
+ commission_toto + parseInt(val2.commission_amount, 10);
+ });
+ // defaultShift.addCommission(
+ // parseInt(val.commission_amount, 10),
+ // );
+ totalAmountDue =
+ parseInt(totalAmountDue, 10) +
+ parseInt(val.price.toFixed(2), 10) *
+ parseInt(val.qty.toFixed(2), 10);
+ if (val.category && val.category !== "No Category") {
+ props.shiftStore.defaultShift.categoriesAmounts({
+ name: val.category,
+ total_amount:
+ parseInt(val.price.toFixed(2), 10) *
+ parseInt(val.qty.toFixed(2), 10),
+ });
+ }
+ if (props.stateStore.payment_state[0].selected) {
+ props.shiftStore.defaultShift.mopAmounts({
+ name: props.stateStore.payment_state[0].selected,
+ total_amount:
+ parseInt(val.price.toFixed(2), 10) *
+ parseInt(val.qty.toFixed(2), 10),
+ });
+ }
+ });
+ if (props.receiptStore.defaultReceipt.orderType !== "None") {
+ props.shiftStore.defaultShift.addOrderType({
+ amount: parseFloat(totalAmountDue, 10),
+ type: props.receiptStore.defaultReceipt.orderType,
+ });
+ }
+ props.shiftStore.defaultShift.addTotalSales(totalAmountDue);
+ if (res) {
+ let writePromises = [];
+
+ for (
+ let printedReceipts = 0;
+ printedReceipts <
+ parseInt(
+ props.printerStore.companySettings[0].changeNoReceipts,
+ 10,
+ );
+ printedReceipts += 1
+ ) {
+ writePromises = [];
+
+ writePromises.push(BluetoothSerial.write(TinyPOS.init()));
+
+ // Header
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${
+ props.printerStore.companySettings.length > 0
+ ? props.printerStore.companySettings[0].name
+ ? props.printerStore.companySettings[0].name.toString()
+ : ""
+ : ""
+ }`,
+ { align: "center", size: "doubleheight" },
+ true,
+ ),
+ ),
+ );
+
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${
+ props.printerStore.companySettings.length > 0
+ ? props.printerStore.companySettings[0].header.toString()
+ : ""
+ }`,
+ { align: "center", size: "normal" },
+ true,
+ ),
+ ),
+ );
+
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ "================================",
+ { size: "normal" },
+ true,
+ ),
+ ),
+ );
+
+ // Date
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${moment().format("YYYY/MM/D hh:mm:ss SSS")}`,
+ { size: "normal" },
+ true,
+ ),
+ ),
+ );
+
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ "================================",
+ { size: "normal" },
+ true,
+ ),
+ ),
+ );
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ strings.Cashier +
+ `${props.attendantStore.defaultAttendant.user_name}`,
+ { align: "left", size: "normal" },
+ true,
+ ),
+ ),
+ );
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ strings.TransactionNo + `${finalReceiptNumber}`,
+ { align: "left", size: "normal" },
+ true,
+ ),
+ ),
+ );
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ "================================",
+ { size: "normal" },
+ true,
+ ),
+ ),
+ );
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ "Mode of payment: " +
+ props.stateStore.payment_state[0].selected,
+ { align: "left", size: "normal" },
+ true,
+ ),
+ ),
+ );
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ "================================",
+ { size: "normal" },
+ true,
+ ),
+ ),
+ );
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ strings.Purchases,
+ { align: "center", size: "normal" },
+ true,
+ ),
+ ),
+ );
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ strings.Items +
+ " " +
+ strings.Amount +
+ " ",
+ { align: "left", size: "normal", weight: "bold" },
+ true,
+ ),
+ ),
+ );
+
+ props.receiptStore.defaultReceipt.lines.map(val => {
+ let finalLines = "";
+
+ const name = val.item_name;
+
+ if (name.length > 14) {
+ let quotientValue = name.length / 14;
+ for (
+ let quotient = 0;
+ quotient < parseInt(quotientValue, 10);
+ quotient += 1
+ ) {
+ let currentCounter = quotient * 14;
+ let nameCounter = "";
+ for (
+ let n = currentCounter;
+ n < (quotient + 1) * 14;
+ n += 1
+ ) {
+ nameCounter = nameCounter + name[n];
+ }
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${nameCounter}`,
+ { align: "left", size: "normal" },
+ true,
+ ),
+ ),
+ );
+ }
+ if (name.length - parseInt(quotientValue, 10) * 14 > 0) {
+ let nameCounterOverflow = "";
+ for (
+ let m = parseInt(quotientValue, 10) * 14;
+ m < name.length;
+ m += 1
+ ) {
+ nameCounterOverflow = nameCounterOverflow + name[m];
+ }
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${nameCounterOverflow}`,
+ { align: "left", size: "normal" },
+ true,
+ ),
+ ),
+ );
+ }
+ } else {
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${name}`,
+ { align: "left", size: "normal" },
+ true,
+ ),
+ ),
+ );
+ }
+
+ let priceString = formatNumber(
+ parseFloat(val.price, 10),
+ ).toString();
+ let qtyString = val.qty.toString();
+ let amountString = formatNumber(
+ parseFloat(val.price, 10) * parseFloat(val.qty, 10),
+ ).toString();
+
+ for (let ps = 0; ps < 12 - priceString.length; ps += 1) {
+ finalLines = finalLines + " ";
+ }
+
+ finalLines = finalLines + priceString;
+
+ for (let qt = 0; qt < 6 - qtyString.length; qt += 1) {
+ finalLines = finalLines + " ";
+ }
+ finalLines = finalLines + qtyString;
+
+ for (let as = 0; as < 14 - amountString.length; as += 1) {
+ finalLines = finalLines + " ";
+ }
+
+ finalLines = finalLines + amountString;
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${finalLines}`,
+ { align: "left", size: "normal" },
+ true,
+ ),
+ ),
+ );
+ if (printedReceipts === 0) {
+ totalPurchase =
+ parseFloat(totalPurchase, 10) +
+ parseFloat(val.price, 10) * parseFloat(val.qty, 10);
+ }
+ });
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ "================================",
+ { align: "left", size: "normal", weight: "bold" },
+ true,
+ ),
+ ),
+ );
+
+ let subTotal = strings.Subtotal;
+ let sub = formatNumber(
+ parseFloat(props.receiptStore.defaultReceipt.subtotal, 10),
+ ).toString();
+ for (let t = 0; t < 23 - sub.length; t += 1) {
+ subTotal = subTotal + " ";
+ }
+ subTotal = subTotal + sub;
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${subTotal}`,
+ { align: "left", size: "normal" },
+ true,
+ ),
+ ),
+ );
+ let taxValue = strings.Tax;
+ let tax = formatNumber(
+ parseFloat(
+ props.stateStore.enableOverallTax
+ ? props.receiptStore.defaultReceipt.get_tax_total
+ : props.receiptStore.defaultReceipt
+ .get_tax_total_based_on_each_item,
+ 10,
+ ),
+ ).toString();
+ for (let t = 0; t < 29 - tax.length; t += 1) {
+ taxValue = taxValue + " ";
+ }
+ taxValue = taxValue + tax;
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${taxValue}`,
+ { align: "left", size: "normal" },
+ true,
+ ),
+ ),
+ );
+ let discountValue = strings.Discount;
+ let discount = formatNumber(
+ parseFloat(props.receiptStore.defaultReceipt.discounts, 10),
+ ).toString();
+ for (let d = 0; d < 24 - discount.length; d += 1) {
+ discountValue = discountValue + " ";
+ }
+ discountValue = discountValue + discount;
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${discountValue}`,
+ { align: "left", size: "normal" },
+ true,
+ ),
+ ),
+ );
+
+ let commissionValue = strings.Commission;
+
+ let commission_total = formatNumber(
+ parseFloat(commission_toto, 10),
+ ).toString();
+ for (let d = 0; d < 22 - commission_total.length; d += 1) {
+ commissionValue = commissionValue + " ";
+ }
+ commissionValue = commissionValue + commission_total;
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${commissionValue}`,
+ { align: "left", size: "normal" },
+ true,
+ ),
+ ),
+ );
+
+ let total = "";
+ total = total + strings.TotalAmount;
+
+ for (
+ let totalLength = 0;
+ totalLength <
+ 20 -
+ formatNumber(parseFloat(totalPurchase, 10)).toString()
+ .length;
+ totalLength += 1
+ ) {
+ total = total + " ";
+ }
+ total =
+ total +
+ formatNumber(
+ parseFloat(totalPurchase, 10) -
+ parseFloat(
+ props.receiptStore.defaultReceipt.discounts,
+ 10,
+ ) +
+ parseFloat(
+ props.stateStore.enableOverallTax
+ ? props.receiptStore.defaultReceipt.get_tax_total
+ : props.receiptStore.defaultReceipt
+ .get_tax_total_based_on_each_item,
+ 10,
+ ),
+ ).toString();
+
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${total}`,
+ { align: "left", size: "normal", weight: "bold" },
+ true,
+ ),
+ ),
+ );
+ let cash = strings.Cash;
+ for (
+ let cashLength = 0;
+ cashLength <
+ 28 -
+ formatNumber(
+ props.stateStore.settings_state[0].multipleMop
+ ? parseFloat(props.stateStore.payment_amount)
+ : parseFloat(props.stateStore.payment_value, 10),
+ ).toString().length;
+ cashLength += 1
+ ) {
+ cash = cash + " ";
+ }
+ cash =
+ cash +
+ formatNumber(
+ props.stateStore.settings_state[0].multipleMop
+ ? parseFloat(props.stateStore.payment_amount)
+ : parseFloat(props.stateStore.payment_value, 10),
+ ).toString();
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${cash}`,
+ { align: "left", size: "normal", weight: "bold" },
+ true,
+ ),
+ ),
+ );
+ let change = strings.Change;
+ let changeValue = formatNumber(
+ parseFloat(
+ (props.stateStore.settings_state[0].multipleMop
+ ? parseFloat(props.stateStore.payment_amount)
+ : parseFloat(props.stateStore.payment_value, 10)) -
+ (parseFloat(totalPurchase, 10) -
+ parseFloat(
+ props.receiptStore.defaultReceipt.discounts,
+ 10,
+ ) +
+ parseFloat(
+ props.stateStore.enableOverallTax
+ ? props.receiptStore.defaultReceipt.get_tax_total
+ : props.receiptStore.defaultReceipt
+ .get_tax_total_based_on_each_item,
+ 10,
+ )),
+ 10,
+ ),
+ ).toString();
+ for (
+ let changeLength = 0;
+ changeLength < 26 - changeValue.length;
+ changeLength += 1
+ ) {
+ change = change + " ";
+ }
+ change = change + changeValue;
+
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${change}`,
+ { align: "left", size: "normal", weight: "bold" },
+ true,
+ ),
+ ),
+ );
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ "================================",
+ { size: "normal" },
+ true,
+ ),
+ ),
+ );
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ strings.ThisServesAsYour,
+ { align: "center", size: "doubleheight" },
+ true,
+ ),
+ ),
+ );
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ strings.OfficialReceipt + "\n",
+ { align: "center", size: "doubleheight" },
+ true,
+ ),
+ ),
+ );
+ writePromises.push(
+ BluetoothSerial.write(
+ TinyPOS.bufferedText(
+ `${
+ props.printerStore.companySettings.length > 0
+ ? props.printerStore.companySettings[0].footer.toString()
+ : ""
+ }`,
+ { align: "center", size: "normal" },
+ true,
+ ),
+ ),
+ );
+ // Add 3 new lines
+ writePromises.push(
+ BluetoothSerial.write(TinyPOS.bufferedLine(3)),
+ );
+ }
+ // Push drawer
+ writePromises.push(
+ BluetoothSerial.write(TinyPOS.kickCashDrawer()),
+ );
+ writePromises.push(
+ BluetoothSerial.write(TinyPOS.kickCashDrawer()),
+ );
+ Promise.all(writePromises)
+ .then(res2 => {
+ receiptCurrent.completed(
+ props.attendantStore.defaultAttendant.user_name,
+ );
+
+ props.receiptStore.defaultReceipt.changeTaxesAmount(
+ props.stateStore.enableOverallTax
+ ? props.receiptStore.defaultReceipt.get_tax_total
+ : props.receiptStore.defaultReceipt
+ .get_tax_total_based_on_each_item,
+ );
+ // add to row
+
+ payment_add(props);
+
+ // Reset payment amount
+ // setState({
+ // modalVisible: false,
+ // paymentAmount: 0,
+ // });
+ props.stateStore.changeValue(
+ "modalVisible",
+ false,
+ "Payment",
+ );
+ props.stateStore.changeValue("paymentAmount", 0, "Payment");
+
+ Toast.show({
+ text: strings.TransactionCompleted,
+ duration: 5000,
+ });
+ })
+ .catch(err => {
+ receiptCurrent.completed(
+ props.attendantStore.defaultAttendant.user_name,
+ );
+
+ props.receiptStore.defaultReceipt.changeTaxesAmount(
+ props.stateStore.enableOverallTax
+ ? props.receiptStore.defaultReceipt.get_tax_total
+ : props.receiptStore.defaultReceipt
+ .get_tax_total_based_on_each_item,
+ );
+
+ payment_add(props);
+ props.stateStore.changeValue(
+ "modalVisible",
+ false,
+ "Payment",
+ );
+ props.stateStore.changeValue("paymentAmount", 0, "Payment");
+
+ Toast.show({
+ text: err.message + strings.TransactionCompleted,
+ buttonText: strings.Okay,
+ position: "bottom",
+ duration: 5000,
+ });
+ });
+ } else {
+ receiptCurrent.completed(
+ props.attendantStore.defaultAttendant.user_name,
+ );
+
+ props.receiptStore.defaultReceipt.changeTaxesAmount(
+ props.stateStore.enableOverallTax
+ ? props.receiptStore.defaultReceipt.get_tax_total
+ : props.receiptStore.defaultReceipt
+ .get_tax_total_based_on_each_item,
+ );
+
+ // add to row
+ payment_add(props);
+
+ // this.setState({
+ // modalVisible: false,
+ // paymentAmount: 0,
+ // });
+ props.stateStore.changeValue("modalVisible", false, "Payment");
+ props.stateStore.changeValue("paymentAmount", 0, "Payment");
+ Toast.show({
+ text:
+ strings.TransactionCompleted[
+ strings.UnableToConnectPrinter
+ ],
+ buttonText: strings.Okay,
+ position: "bottom",
+ duration: 6000,
+ });
+ }
+
+ const { defaultShift } = props.shiftStore;
+
+ // If shift started and shift hasn't ended
+ if (defaultShift.shiftStarted && !defaultShift.shiftEnded) {
+ // Set the default receipt
+ const { defaultReceipt } = props.receiptStore;
+
+ // set shift
+ defaultReceipt.setShift(defaultShift._id);
+
+ const { ending_cash } = defaultShift;
+
+ // Set the end cash
+ defaultShift.setEndCash(ending_cash + defaultReceipt.netTotal);
+ }
+
+ // props.receiptStore.defaultReceipt.clear();
+ props.receiptStore.add(props.receiptStore.defaultReceipt);
+ props.receiptStore.setPreviousReceipt(
+ props.receiptStore.defaultReceipt,
+ );
+ let discountValueForDisplay =
+ props.receiptStore.defaultReceipt.discounts;
+ let taxesValueForDisplay = props.stateStore.enableOverallTax
+ ? props.receiptStore.defaultReceipt.get_tax_total
+ : props.receiptStore.defaultReceipt
+ .get_tax_total_based_on_each_item;
+ props.receiptStore.newReceipt(
+ props.printerStore.companySettings[0].tax,
+ );
+ props.receiptStore.setLastScannedBarcode("");
+ props.receiptStore.unselectReceiptLine();
+ props.stateStore.changeValue("selected", "Cash", "Payment");
+ change_navigation(
+ props,
+ totalPurchase,
+ discountValueForDisplay,
+ taxesValueForDisplay,
+ );
+ },
+ },
+ ],
+ );
+ });
+ }
+}
+
+export function payment_add(props) {
+ props.paymentStore.add({
+ receipt: props.receiptStore.defaultReceipt._id.toString(),
+ date: Date.now(),
+ paid: props.stateStore.settings_state[0].multipleMop
+ ? parseFloat(props.stateStore.payment_amount)
+ : parseInt(props.stateStore.payment_value, 10),
+ type: props.stateStore.settings_state[0].multipleMop
+ ? props.stateStore.payment_types
+ : not_multiple_payment(props),
+ dateUpdated: Date.now(),
+ syncStatus: false,
+ });
+}
+
+export function not_multiple_payment(props) {
+ let single_payment = [];
+
+ single_payment.push({
+ type: props.stateStore.payment_state[0].selected,
+ amount: parseFloat(props.stateStore.amount_due, 10),
+ });
+ return JSON.stringify(single_payment);
+}
+export function change_navigation(
+ props,
+ totalPurchase,
+ discountValueForDisplay,
+ taxesValueForDisplay,
+) {
+ props.navigation.navigate("Sales", {
+ cash: props.stateStore.settings_state[0].multipleMop
+ ? parseFloat(props.stateStore.payment_amount)
+ : props.stateStore.payment_value,
+ change: parseFloat(
+ (props.stateStore.settings_state[0].multipleMop
+ ? parseFloat(props.stateStore.payment_amount)
+ : parseFloat(props.stateStore.payment_value, 10)) -
+ (parseFloat(totalPurchase, 10) -
+ parseFloat(discountValueForDisplay, 10) +
+ parseFloat(taxesValueForDisplay, 10)),
+ 10,
+ ),
+ });
+}
diff --git a/src/container/ReceiptInfoContainer/index.js b/src/container/ReceiptInfoContainer/index.js
index 10d57bf..8a664e9 100644
--- a/src/container/ReceiptInfoContainer/index.js
+++ b/src/container/ReceiptInfoContainer/index.js
@@ -476,36 +476,35 @@ export default class ReceiptInfoContainer extends React.Component {
),
),
);
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- "\n" +
- strings.POSProvider +
- "Bai Web and Mobile Lab\n" +
- "Insular Life Bldg, Don Apolinar\n" +
- "Velez cor. Oldarico Akut St.,\n" +
- "Cagayan de Oro, 9000,\n" +
- "Misamis Oriental\n" +
- strings.AccredNo +
- strings.DateIssued +
- strings.ValidUntil,
- { align: "left", size: "normal" },
- true,
- ),
- ),
- );
- writePromises.push(
- BluetoothSerial.write(
- TinyPOS.bufferedText(
- strings.ThisReceiptShallBeValidFor +
- strings.FiveYearsFromTheDateOf +
- strings.ThePermitToUse,
- { align: "center", size: "normal" },
- true,
- ),
- ),
- );
-
+ // writePromises.push(
+ // BluetoothSerial.write(
+ // TinyPOS.bufferedText(
+ // "\n" +
+ // strings.POSProvider +
+ // "Bai Web and Mobile Lab\n" +
+ // "Insular Life Bldg, Don Apolinar\n" +
+ // "Velez cor. Oldarico Akut St.,\n" +
+ // "Cagayan de Oro, 9000,\n" +
+ // "Misamis Oriental\n" +
+ // strings.AccredNo +
+ // strings.DateIssued +
+ // strings.ValidUntil,
+ // { align: "left", size: "normal" },
+ // true,
+ // ),
+ // ),
+ // );
+ // writePromises.push(
+ // BluetoothSerial.write(
+ // TinyPOS.bufferedText(
+ // strings.ThisReceiptShallBeValidFor +
+ // strings.FiveYearsFromTheDateOf +
+ // strings.ThePermitToUse,
+ // { align: "center", size: "normal" },
+ // true,
+ // ),
+ // ),
+ // );
// Add 3 new lines
writePromises.push(BluetoothSerial.write(TinyPOS.bufferedLine(3)));
@@ -554,8 +553,9 @@ export default class ReceiptInfoContainer extends React.Component {
// payment receipt
if (this.state.reasonValue) {
- paymentReceipt.changeReason(this.state.reasonValue);
- paymentReceipt.cancelled(paymentReceipt);
+ paymentReceipt.setCancel(this.state.reasonValue);
+ // paymentReceipt.changeReason(this.state.reasonValue);
+ // paymentReceipt.cancelled(paymentReceipt);
this.props.shiftStore.setNewValues(obj);
// Navigate to payment store
diff --git a/src/container/SalesContainer/index.js b/src/container/SalesContainer/index.js
index 91729e7..2dc545a 100644
--- a/src/container/SalesContainer/index.js
+++ b/src/container/SalesContainer/index.js
@@ -22,7 +22,8 @@ import {
} from "../../utils";
import PriceModalComponent from "@components/PriceModalComponent";
-import SummaryModalComponent from "@components/SummaryModalComponent";
+import ConfirmationModalComponent from "@components/ConfirmationModalComponent";
+// import SummaryModalComponent from "@components/SummaryModalComponent";
import QuantityModalComponent from "@components/QuantityModalComponent";
import ConfirmOrderModalComponent from "@components/ConfirmOrderModalComponent";
import DiscountSelectionModalComponent from "@components/DiscountSelectionModalComponent";
@@ -40,7 +41,6 @@ import {
} from "../../services/tailorder";
import { currentLanguage } from "../../translations/CurrentLanguage";
-
const Sound = require("react-native-sound");
Sound.setCategory("Playback");
const beep = new Sound("beep.mp3", Sound.MAIN_BUNDLE);
@@ -62,10 +62,6 @@ let strings = new LocalizedStrings(translation);
@observer
export default class SalesContainer extends React.Component {
componentWillMount() {
- const { initializeState } = this.props.stateStore;
-
- // Initializing the state store
- initializeState();
this.getBluetoothState();
const { params } = this.props.navigation.state;
@@ -82,6 +78,7 @@ export default class SalesContainer extends React.Component {
"Sales",
);
}
+ this.viewOrders("willMount");
}
async getBluetoothState() {
@@ -113,7 +110,10 @@ export default class SalesContainer extends React.Component {
let line = "";
if (item.category !== "No Category") {
const categoryObj = this.props.categoryStore.find(item.category);
- line = createReceiptLine(item, categoryObj._55.name);
+ line = createReceiptLine(
+ item,
+ categoryObj._55 !== null ? categoryObj._55.name : "No Category",
+ );
} else {
line = createReceiptLine(item, item.category);
}
@@ -223,11 +223,17 @@ export default class SalesContainer extends React.Component {
onDeleteReceiptLine = () => {
const { hideDeleteDialog } = this.props.stateStore;
- const { unselectReceiptLine, defaultReceipt } = this.props.receiptStore;
-
- unselectReceiptLine();
- defaultReceipt.clear();
hideDeleteDialog();
+ if (this.props.attendantStore.defaultAttendant.canApprove) {
+ const { unselectReceiptLine, defaultReceipt } = this.props.receiptStore;
+ unselectReceiptLine();
+ defaultReceipt.clear();
+ hideDeleteDialog();
+ } else {
+ this.props.stateStore.changeConfirmation("AllReceiptLine");
+ const { changeValue } = this.props.stateStore;
+ changeValue("confirmation", true, "Sales");
+ }
};
onBarcodeClick = () => {
@@ -253,11 +259,16 @@ export default class SalesContainer extends React.Component {
const { navigate } = this.props.navigation;
const { defaultShift } = this.props.shiftStore;
const { setAmountDue } = this.props.stateStore;
+ const { allowRoundOff } = this.props.stateStore.settings_state[0];
const { defaultAttendant } = this.props.attendantStore;
if (defaultShift.shiftStarted && !defaultShift.shiftEnded) {
if (defaultShift.attendant === defaultAttendant.user_name) {
- setAmountDue(text.netTotal.toFixed(2));
+ setAmountDue(
+ allowRoundOff
+ ? text.netTotalRoundOff.toString()
+ : text.netTotal.toFixed(2),
+ );
navigate("Payment", { receipt: true });
} else {
showToastDanger(strings.ItIsNotYourShift);
@@ -313,8 +324,17 @@ export default class SalesContainer extends React.Component {
changeValue("selectedDiscount", discount, "Sales");
changeValue("selectedDiscountIndex", index, "Sales");
}
-
onDiscountEdit = val => {
+ if (this.props.attendantStore.defaultAttendant.canApprove) {
+ this.onDiscountApply(val);
+ } else {
+ this.props.stateStore.changeDiscountString(JSON.stringify(val));
+ this.props.stateStore.changeConfirmation("AllDiscount");
+ const { changeValue } = this.props.stateStore;
+ changeValue("confirmation", true, "Sales");
+ }
+ };
+ onDiscountApply = val => {
const { changeValue } = this.props.stateStore;
const { defaultReceipt } = this.props.receiptStore;
const { rows, setDiscount } = this.props.discountStore;
@@ -338,7 +358,6 @@ export default class SalesContainer extends React.Component {
// hide modal
changeValue("discountSelection", false, "Sales");
};
-
confirmReceiptDeleteDialog() {
const { hideDeleteDialog } = this.props.stateStore;
const { deleteDialogVisible } = this.props.stateStore.sales_state[0];
@@ -372,12 +391,16 @@ export default class SalesContainer extends React.Component {
onDiscountChange={(discount, index) =>
this.onDiscountChange(discount, index)
}
- selectedDiscount={this.props.stateStore.sales_state[0].selectedDiscount}
+ selectedDiscount={selectedDiscount ? selectedDiscount : ""}
discountSelection={
- this.props.stateStore.sales_state[0].discountSelection
+ this.props.stateStore.sales_state.length > 0
+ ? this.props.stateStore.sales_state[0].discountSelection
+ : ""
}
discountSelectionStatus={
- this.props.stateStore.sales_state[0].discountSelectionStatus
+ this.props.stateStore.sales_state.length > 0
+ ? this.props.stateStore.sales_state[0].discountSelectionStatus
+ : ""
}
onClick={() =>
this.props.stateStore.changeValue("discountSelection", false, "Sales")
@@ -507,55 +530,72 @@ export default class SalesContainer extends React.Component {
changeValue("visibleSummaryModal", false, "Sales");
};
- summaryDialog() {
- const { previousReceipt } = this.props.receiptStore;
- const { cash, change } = this.props.stateStore.sales_state[0];
- const { countryCode } = this.props.printerStore.companySettings[0];
+ // summaryDialog() {
+ // const { previousReceipt } = this.props.receiptStore;
+ // const { enableOverallTax } = this.props.stateStore;
+ // const { cash, change } = this.props.stateStore.sales_state[0];
+ // const { countryCode } = this.props.printerStore.companySettings[0];
+ // console.log(this.props.stateStore.sales_state[0])
+ // return (
+ // 0 ? cash : 0}
+ // change={change > 0 ? change : 0}
+ // onClose={this.closeSummary}
+ // visibility={previousReceipt ? false : false}
+ // lines={previousReceipt ? previousReceipt.lines.slice() : []}
+ // details={
+ // previousReceipt && previousReceipt.lines ? previousReceipt : {}
+ // }
+ // currency={countryCode !== undefined ? countryCode : "PHP"}
+ // />
+ // );
+ // }
- return (
-
- );
- }
onQuantitySubmit = quantity => {
+ if (
+ this.props.attendantStore.defaultAttendant.canApprove ||
+ parseFloat(quantity.discount) === 0
+ ) {
+ this.setEditedFigures(quantity);
+ } else if (
+ !this.props.attendantStore.defaultAttendant.canApprove &&
+ parseFloat(quantity.discount) > 0
+ ) {
+ this.props.stateStore.changeDiscountString(JSON.stringify(quantity));
+ this.props.stateStore.changeConfirmation("SingleDiscount");
+ const { changeValue } = this.props.stateStore;
+ changeValue("confirmation", true, "Sales");
+ }
// line
+ };
+ setEditedFigures = figures => {
this.setState({ onChangeStatues: false });
const line = this.props.receiptStore.selectedLine;
- const qty = parseFloat(quantity.quantity)
- ? parseFloat(quantity.quantity)
- : parseFloat(quantity.defaultQty);
+ const qty = parseFloat(figures.quantity)
+ ? parseFloat(figures.quantity)
+ : parseFloat(figures.defaultQty);
if (line.sold_by === "Each") {
if (isFloat(qty)) {
showToast(strings.QuantityIsNotAllowed, "warning");
} else {
- showToast(strings.ReceiptLineIsModified);
line.setQuantity(Number(qty.toFixed(2)));
}
} else {
- showToast(strings.ReceiptLineIsModified);
line.setQuantity(Number(qty.toFixed(2)));
}
- const price = parseFloat(quantity.price)
- ? parseFloat(quantity.price)
- : parseFloat(quantity.defaultPrice);
+ const price = parseFloat(figures.price)
+ ? parseFloat(figures.price)
+ : parseFloat(figures.defaultPrice);
// set the price
line.setPrice(Number(price.toFixed(2)));
line.setDiscountRate(
- parseFloat(quantity.discount) > 0 ? parseFloat(quantity.discount) : 0,
- quantity.percentageType,
+ parseFloat(figures.discount) > 0 ? parseFloat(figures.discount) : 0,
+ figures.percentageType,
);
// unselect the line
@@ -568,10 +608,70 @@ export default class SalesContainer extends React.Component {
// remove the receipt store
this.props.stateStore.changeValue("quantityModalVisible", false, "Sales");
};
+ execute_method = pin => {
+ const { changeValue } = this.props.stateStore;
+ this.props.attendantStore.findAttendantBasedOnRole(pin).then(result => {
+ if (result) {
+ changeValue("confirmation", false, "Sales");
+ if (this.props.stateStore.currentConfirmation === "ReceiptLine") {
+ this.onReceiptLineDelete(this.props.stateStore.index_value);
+ showToast("Successfully Deleted Receiptline(s)");
+ } else if (
+ this.props.stateStore.currentConfirmation === "AllReceiptLine"
+ ) {
+ const { hideDeleteDialog } = this.props.stateStore;
+ const {
+ unselectReceiptLine,
+ defaultReceipt,
+ } = this.props.receiptStore;
+ unselectReceiptLine();
+ defaultReceipt.clear();
+ hideDeleteDialog();
+ showToast("Successfully Deleted Receiptline(s)");
+ } else if (
+ this.props.stateStore.currentConfirmation === "AllDiscount"
+ ) {
+ this.onDiscountApply(
+ JSON.parse(this.props.stateStore.discount_string),
+ );
+ showToast("Successfully Applied Discount");
+ } else if (
+ this.props.stateStore.currentConfirmation === "SingleDiscount"
+ ) {
+ this.setEditedFigures(
+ JSON.parse(this.props.stateStore.discount_string),
+ );
+ showToast("Successfully Applied Discount");
+ }
+ } else {
+ showToastDanger("Approvers Pin Invalid");
+ }
+ });
+ };
+ confirmationModal() {
+ const { changeValue } = this.props.stateStore;
+ return (
+ this.execute_method(pin)}
+ onClose={() => changeValue("confirmation", false, "Sales")}
+ />
+ );
+ }
+ showConfirmationModalReceiptLine = index => {
+ if (this.props.attendantStore.defaultAttendant.canApprove) {
+ this.onReceiptLineDelete(index);
+ } else {
+ this.props.stateStore.changeConfirmation("ReceiptLine");
+ this.props.stateStore.changeIndex(index);
+ const { changeValue } = this.props.stateStore;
+ changeValue("confirmation", true, "Sales");
+ }
+ };
onReceiptLineDelete = index => {
const { queueOrigin, currentTable } = this.props.stateStore;
-
this.props.receiptStore.unselectReceiptLine();
const receipt = this.props.receiptStore.defaultReceipt;
@@ -604,7 +704,7 @@ export default class SalesContainer extends React.Component {
this.props.stateStore.changeValue("quantityModalVisible", true, "Sales");
};
- viewOrders = () => {
+ viewOrders = status => {
const {
setViewingOrder,
setLoadingOrder,
@@ -612,8 +712,8 @@ export default class SalesContainer extends React.Component {
queueOrigin,
} = this.props.stateStore;
- setViewingOrder(true);
- setLoadingOrder(true);
+ setViewingOrder(!status);
+ setLoadingOrder(!status);
const url = `${queueOrigin}/api/v1/orders/`;
@@ -652,6 +752,7 @@ export default class SalesContainer extends React.Component {
setViewingOrder,
} = this.props.stateStore;
const { defaultReceipt } = this.props.receiptStore;
+ const { defaultShift } = this.props.shiftStore;
const table = { id: currentTable };
showAlert(
@@ -662,6 +763,7 @@ export default class SalesContainer extends React.Component {
setCurrentTable(-1);
defaultReceipt.clear();
setViewingOrder(false);
+ defaultShift.orderVoid();
showToast(`${strings.Order} ${res.table_no} ${strings.IsCancelled}`);
});
},
@@ -766,7 +868,6 @@ export default class SalesContainer extends React.Component {
tableNo = null;
}
const order = getOrder(orderType, items, tableNo);
-
sendOrder(queueOrigin, order)
.then(res => {
unselectReceiptLine();
@@ -853,19 +954,22 @@ export default class SalesContainer extends React.Component {
return (
{this.discountSelectionDialog()}
- {this.summaryDialog()}
+ {/*{this.summaryDialog()}*/}
{this.confirmReceiptDeleteDialog()}
{this.quantityEditDialog()}
{this.priceInputDialog()}
{this.onConfirmOrderDialog()}
+ {this.confirmationModal()}
0
@@ -907,7 +1011,7 @@ export default class SalesContainer extends React.Component {
// receipt line
onPaymentClick={this.onPaymentClick}
onReceiptLineEdit={this.onReceiptLineEdit}
- onReceiptLineDelete={this.onReceiptLineDelete}
+ onReceiptLineDelete={this.showConfirmationModalReceiptLine}
// empty rows
onEndReached={this.onEndReached}
onLongPressItem={this.onLongPressItem}
@@ -935,6 +1039,7 @@ export default class SalesContainer extends React.Component {
onChangeTable={this.onChangeTable}
onReprintOrder={this.onReprintOrder}
isCurrencyDisabled={this.props.stateStore.isCurrencyDisabled}
+ enableOverallTax={this.props.stateStore.enableOverallTax}
/>
);
diff --git a/src/container/SettingsContainer/constants.json b/src/container/SettingsContainer/constants.json
index 4267554..baaf5a4 100644
--- a/src/container/SettingsContainer/constants.json
+++ b/src/container/SettingsContainer/constants.json
@@ -120,5 +120,6 @@
{"name":"XOF"},
{"name":"XPF"},
{"name":"ZAR"},
- {"name":"ZMW"}
+ {"name":"ZMW"},
+ {"name":"MWK"}
]
\ No newline at end of file
diff --git a/src/container/SettingsContainer/index.js b/src/container/SettingsContainer/index.js
index 6dec2ae..505758a 100644
--- a/src/container/SettingsContainer/index.js
+++ b/src/container/SettingsContainer/index.js
@@ -86,22 +86,51 @@ export default class SettingsContainer extends React.Component {
);
}
if (this.props.printerStore.companySettings.length > 0) {
- // Alert.alert("", this.props.printerStore.companySettings[0].name + " " + this.props.printerStore.companySettings[0].header + " " + this.props.printerStore.companySettings[0].footer)
- // this.setState({
- // companyName: this.props.printerStore.companySettings[0].name.toString(),
- // companyHeader: this.props.printerStore.companySettings[0].header.toString(),
- // companyFooter: this.props.printerStore.companySettings[0].footer.toString(),
- // });
this.props.stateStore.changeValue(
"companyName",
this.props.printerStore.companySettings[0].name.toString(),
"Settings",
);
+ this.props.stateStore.changeValue(
+ "smallSizeIcon",
+ this.props.printerStore.companySettings[0].smallSizeIcon,
+ "Settings",
+ );
+ this.props.stateStore.changeValue(
+ "mediumSizeIcon",
+ this.props.printerStore.companySettings[0].mediumSizeIcon,
+ "Settings",
+ );
+ this.props.stateStore.changeValue(
+ "largeSizeIcon",
+ this.props.printerStore.companySettings[0].largeSizeIcon,
+ "Settings",
+ );
+ this.props.stateStore.changeValue(
+ "multipleMop",
+ this.props.printerStore.companySettings[0].multipleMop,
+ "Settings",
+ );
+ this.props.stateStore.changeValue(
+ "allowRoundOff",
+ this.props.printerStore.companySettings[0].allowRoundOff,
+ "Settings",
+ );
+ this.props.stateStore.changeValue(
+ "hideMenuBar",
+ this.props.printerStore.companySettings[0].hideMenuBar,
+ "Settings",
+ );
this.props.stateStore.changeValue(
"tax",
this.props.printerStore.companySettings[0].tax.toString(),
"Settings",
);
+ this.props.stateStore.changeValue(
+ "changeNoReceipts",
+ this.props.printerStore.companySettings[0].changeNoReceipts.toString(),
+ "Settings",
+ );
this.props.stateStore.changeValue(
"companyHeader",
this.props.printerStore.companySettings[0].header.toString(),
@@ -130,6 +159,9 @@ export default class SettingsContainer extends React.Component {
this.props.stateStore.changeCompanyCheckBox(
this.props.printerStore.companySettings[0].currencyDisable,
);
+ this.props.stateStore.changeOverallTax(
+ this.props.printerStore.companySettings[0].enableOverallTax,
+ );
}
for (let i = 0; i < this.props.printerStore.rows.length; i += 1) {
if (this.props.printerStore.rows[i].defaultPrinter) {
@@ -153,7 +185,6 @@ export default class SettingsContainer extends React.Component {
this.props.printerStore.rows[i]._id,
"Settings",
);
-
BluetoothSerial.connect(this.props.printerStore.rows[i].macAddress)
.then(() => {
// this.setState({
@@ -189,6 +220,7 @@ export default class SettingsContainer extends React.Component {
BluetoothStatus.enable(true);
}
}
+
onButtonPress = value => {
this.props.printerStore.addFoundDevices(value);
};
@@ -371,7 +403,10 @@ export default class SettingsContainer extends React.Component {
header: this.props.stateStore.settings_state[0].companyHeader,
footer: this.props.stateStore.settings_state[0].companyFooter,
countryCode: this.props.stateStore.settings_state[0].companyCountry,
+ enableOverallTax: this.props.stateStore.enableOverallTax,
currencyDisable: this.props.stateStore.isCurrencyDisabled,
+ changeNoReceipts: this.props.stateStore.settings_state[0]
+ .changeNoReceipts,
});
} else {
this.props.printerStore.addCompany({
@@ -383,6 +418,9 @@ export default class SettingsContainer extends React.Component {
footer: this.props.stateStore.settings_state[0].companyFooter,
countryCode: this.props.stateStore.settings_state[0].companyCountry,
currencyDisable: this.props.stateStore.isCurrencyDisabled,
+ enableOverallTax: this.props.stateStore.enableOverallTax,
+ changeNoReceipts: this.props.stateStore.settings_state[0]
+ .changeNoReceipts,
});
}
@@ -409,6 +447,14 @@ export default class SettingsContainer extends React.Component {
});
}
};
+ onSaveNoReceipts = receiptNo => {
+ const { stateStore, printerStore } = this.props;
+ stateStore.changeValue("changeNoReceipts", receiptNo, "Settings");
+ let company = printerStore.findCompany(printerStore.companySettings[0]._id);
+ company.edit({
+ changeNoReceipts: receiptNo,
+ });
+ };
bluetoothScannerStatus(text) {
if (this.props.printerStore.bluetooth.length > 0) {
let bluetoothScanner = this.props.printerStore.findBluetoothScanner(
@@ -477,6 +523,7 @@ export default class SettingsContainer extends React.Component {
pin_code: values.pin,
role: values.role,
canLogin: values.canLogin,
+ canApprove: values.canApprove,
commission:
parseInt(values.commission, 10) > 0
? parseInt(values.commission, 10)
@@ -500,9 +547,6 @@ export default class SettingsContainer extends React.Component {
});
}
});
-
- // this.props.stateStore.changeValue("attendants", JSON.stringify(this.props.attendantStore.rows.slice()), "Settings")
- // this.props.stateStore.changeValue("attendantsInfo",{}, "Settings")
} else if (values.status === "Edit Attendant") {
const valueAttendant = await this.props.attendantStore.find(
values.id,
@@ -514,6 +558,7 @@ export default class SettingsContainer extends React.Component {
pin_code: values.pin,
role: values.role,
canLogin: values.canLogin,
+ canApprove: values.canApprove,
commission:
parseInt(values.commission, 10) > 0
? parseInt(values.commission, 10)
@@ -595,6 +640,7 @@ export default class SettingsContainer extends React.Component {
pin_code: values.pin,
role: values.role,
canLogin: values.canLogin,
+ canApprove: values.canApprove,
commission:
parseInt(values.commission, 10) > 0
? parseInt(values.commission, 10)
@@ -632,6 +678,7 @@ export default class SettingsContainer extends React.Component {
pin_code: values.pin,
role: values.role,
canLogin: values.canLogin,
+ canApprove: values.canApprove,
commission:
parseInt(values.commission, 10) > 0
? parseInt(values.commission, 10)
@@ -817,6 +864,62 @@ export default class SettingsContainer extends React.Component {
],
);
};
+ toggleItemSize = size => {
+ const { stateStore } = this.props;
+ stateStore.changeValue("smallSizeIcon", size === "Small", "Settings");
+ stateStore.changeValue("mediumSizeIcon", size === "Medium", "Settings");
+ stateStore.changeValue("largeSizeIcon", size === "Large", "Settings");
+
+ if (this.props.printerStore.companySettings.length > 0) {
+ let company = this.props.printerStore.findCompany(
+ this.props.printerStore.companySettings[0]._id,
+ );
+ company.edit({
+ smallSizeIcon: size === "Small",
+ mediumSizeIcon: size === "Medium",
+ largeSizeIcon: size === "Large",
+ });
+ }
+ };
+ toggleMultipleMop = () => {
+ const { stateStore } = this.props;
+ const { multipleMop } = stateStore.settings_state[0];
+ stateStore.changeValue("multipleMop", !multipleMop, "Settings");
+ if (this.props.printerStore.companySettings.length > 0) {
+ let company = this.props.printerStore.findCompany(
+ this.props.printerStore.companySettings[0]._id,
+ );
+ company.edit({
+ multipleMop: !multipleMop,
+ });
+ }
+ };
+ toggleAllowRoundOff = () => {
+ const { stateStore } = this.props;
+ const { allowRoundOff } = stateStore.settings_state[0];
+ stateStore.changeValue("allowRoundOff", !allowRoundOff, "Settings");
+ if (this.props.printerStore.companySettings.length > 0) {
+ let company = this.props.printerStore.findCompany(
+ this.props.printerStore.companySettings[0]._id,
+ );
+ company.edit({
+ allowRoundOff: !allowRoundOff,
+ });
+ }
+ };
+ toggleHideMenuBar = () => {
+ const { stateStore } = this.props;
+ const { hideMenuBar } = stateStore.settings_state[0];
+ stateStore.changeValue("hideMenuBar", !hideMenuBar, "Settings");
+ if (this.props.printerStore.companySettings.length > 0) {
+ let company = this.props.printerStore.findCompany(
+ this.props.printerStore.companySettings[0]._id,
+ );
+ company.edit({
+ hideMenuBar: !hideMenuBar,
+ });
+ }
+ };
render() {
strings.setLanguage(currentLanguage().companyLanguage);
const {
@@ -845,6 +948,10 @@ export default class SettingsContainer extends React.Component {
availableDevicesChangeValue={text =>
stateStore.changeValue("availableDevices", text, "Settings")
}
+ toggleItemSize={size => this.toggleItemSize(size)}
+ toggleMultipleMop={size => this.toggleMultipleMop(size)}
+ toggleAllowRoundOff={this.toggleAllowRoundOff}
+ toggleHideMenuBar={this.toggleHideMenuBar}
checkBoxValueOnChange={this.onCheckBoxValueOnChange}
bluetoothScannerStatus={text => {
stateStore.changeValue("checkBoxBluetoothValue", text, "Settings");
@@ -859,6 +966,7 @@ export default class SettingsContainer extends React.Component {
changeName={text =>
stateStore.changeValue("companyName", text, "Settings")
}
+ changeNoReceipts={this.onSaveNoReceipts}
changeTax={text => stateStore.changeValue("tax", text, "Settings")}
changeCountry={text => this.onChangeCurrency(text)}
changeHeader={text =>
@@ -915,7 +1023,9 @@ export default class SettingsContainer extends React.Component {
toggleTailOrder={stateStore.toggleTailOrder}
onQueueSave={this.onQueueSave}
toggleCurrencyDisabled={this.props.stateStore.toggleCurrencyDisabled}
+ toggleEnableOverallTax={this.props.stateStore.toggleEnableOverallTax}
isCurrencyDisabled={stateStore.isCurrencyDisabled}
+ enableOverallTax={stateStore.enableOverallTax}
// Queue Settings
isEditingQueue={stateStore.isEditingQueue}
setQueueEditing={stateStore.setQueueEditing}
diff --git a/src/store/PosStore/AttendantStore.js b/src/store/PosStore/AttendantStore.js
index 42b0fbc..68b57f3 100644
--- a/src/store/PosStore/AttendantStore.js
+++ b/src/store/PosStore/AttendantStore.js
@@ -19,6 +19,7 @@ export const Attendant = types
user_name: types.string,
pin_code: types.string,
canLogin: types.optional(types.boolean, false),
+ canApprove: types.optional(types.boolean, false),
role: types.optional(types.string, ""),
dateUpdated: types.optional(types.Date, Date.now),
syncStatus: types.optional(types.boolean, false),
@@ -138,6 +139,7 @@ const AttendantStore = types
pin_code: doc.pin_code,
role: doc.role,
canLogin: doc.canLogin ? doc.canLogin : false,
+ canApprove: doc.canApprove ? doc.canApprove : false,
commission: doc.commission,
dateUpdated: doc.dateUpdated,
syncStatus: doc.syncStatus,
@@ -180,6 +182,24 @@ const AttendantStore = types
});
});
},
+ findAttendantBasedOnRole(pin) {
+ return new Promise(function(resolve, reject) {
+ db
+ .find({
+ selector: {
+ canApprove: { $regex: true },
+ pin_code: { $regex: pin },
+ },
+ })
+ .then(result => {
+ if (result.docs.length > 0) {
+ resolve(true);
+ } else {
+ resolve(false);
+ }
+ });
+ });
+ },
}));
const Store = AttendantStore.create({});
diff --git a/src/store/PosStore/DbFunctions.js b/src/store/PosStore/DbFunctions.js
index 5d6a011..2add6ee 100644
--- a/src/store/PosStore/DbFunctions.js
+++ b/src/store/PosStore/DbFunctions.js
@@ -2,9 +2,10 @@ import PouchDB from "pouchdb-react-native";
import SQLite from "react-native-sqlite-2";
import SQLiteAdapterFactory from "pouchdb-adapter-react-native-sqlite";
import { getRoot } from "mobx-state-tree";
-import { unformat } from "accounting-js";
import FrappeFetch from "react-native-frappe-fetch";
-import { Toast } from "native-base";
+import { NetInfo } from "react-native";
+import { showToastDanger } from "../../utils";
+
var validUrl = require("valid-url");
import BackgroundJob from "react-native-background-job";
@@ -16,7 +17,6 @@ export function openAndSyncDB(dbName, withSync = false) {
PouchDB.plugin(require("pouchdb-upsert"));
return db;
}
-
export function syncDB(db, dbName, session) {
// Server URL
const url = `https://${session.db_name}:${session.token}@db.tailpos.com/${
@@ -37,82 +37,77 @@ export function sync(
jobStatus,
store,
) {
- // if (credentials.url !== undefined && credentials.user_name !== undefined && credentials.password !== undefined) {
- if (credentials.url) {
- if (validUrl.isWebUri(credentials.url.toLowerCase())) {
- return FrappeFetch.createClient({
- url: credentials.url.toLowerCase(),
- username: credentials.user_name,
- password: credentials.password,
- })
+ return NetInfo.isConnected.fetch().then(async isConnected => {
+ if (isConnected) {
+ let site_credentials = credentials_info(credentials);
+ let tailpos_object = tailpos_data(
+ jsonObject,
+ type,
+ trashObj,
+ credentials,
+ );
+ return sync_now(site_credentials, tailpos_object, jobStatus, store);
+ } else {
+ showToastDanger("No Internet Connection. Please Check");
+ }
+ });
+}
- .then(responseLog => {
+export function sync_now(site_credentials, tailpos_object, jobStatus, store) {
+ if (site_credentials.url) {
+ if (validUrl.isWebUri(site_credentials.url)) {
+ return FrappeFetch.createClient(site_credentials)
+ .then(() => {
const { Client } = FrappeFetch;
return Client.postApi(
"tailpos_sync.sync_pos.sync_data",
- // "frappe.handler.ping",
- {
- tailposData: JSON.parse(jsonObject),
- trashObject: JSON.parse(trashObj),
- deviceId: credentials.deviceId,
- typeOfSync: type,
- },
+ tailpos_object,
);
})
- .catch(error => {
+ .catch(() => {
store.stateStore.setIsNotSyncing();
BackgroundJob.cancel({ jobKey: "AutomaticSync" });
if (!jobStatus) {
- Toast.show({
- text: "Unable to sync",
- type: "danger",
- duration: 5000,
- });
+ showToastDanger(
+ "Unable to sync. Please check error logs in ERPNext",
+ );
}
})
-
.then(response => response.json())
.then(responseJson => {
- return responseJson.message.data;
+ if (responseJson.message.status) {
+ return responseJson.message.data;
+ } else {
+ showToastDanger(
+ "Unable to sync. Please check error logs in ERPNext",
+ );
+ }
});
} else {
store.stateStore.setIsNotSyncing();
- Toast.show({
- text: "Invalid URL",
- type: "danger",
- duration: 5000,
- });
+ showToastDanger("Invalid URL. Please input valid URL in Sync Settings");
BackgroundJob.cancel({ jobKey: "AutomaticSync" });
}
} else {
BackgroundJob.cancel({ jobKey: "AutomaticSync" });
}
}
-
-export function changeItemsStatusValue(table) {
- table.allDocs({ include_docs: true }).then(entries => {
- if (entries && entries.rows.length > 0) {
- for (var i = 0; i < entries.rows.length; i++) {
- if (entries.rows[i].doc.name) {
- const entry = entries.rows[i].doc;
- const objectValue = {
- name: entry.name,
- soldBy: entry.soldBy,
- price: unformat(entry.price),
- sku: entry.sku,
- barcode: entry.barcode,
- category: entry.category,
- colorAndShape: JSON.stringify(entry.colorAndShape),
- taxes: JSON.stringify(entry.taxes),
- dateUpdated: entry.dateUpdated,
- syncStatus: true,
- };
- editFields(entry, objectValue);
- }
- }
- }
- });
+export function credentials_info(credentials) {
+ return {
+ url: credentials.url.toLowerCase(),
+ username: credentials.user_name,
+ password: credentials.password,
+ };
}
+export function tailpos_data(jsonObject, type, trashObj, credentials) {
+ return {
+ tailposData: JSON.parse(jsonObject),
+ trashObject: JSON.parse(trashObj),
+ deviceId: credentials.deviceId,
+ typeOfSync: type,
+ };
+}
+
export function saveSnapshotToDB(db, snapshot) {
let updateObj = false;
db.upsert(snapshot._id, function(doc) {
@@ -162,8 +157,6 @@ export function getRows(obj, db, numberRows, rowsOptions) {
rowsOptions.skip = 1;
for (var i = 0; i < entries.rows.length; i++) {
if (entries.rows[i].doc.name || entries.rows[i].doc.role) {
- // entries.rows[i].doc.dateUpdated = Date.now();
- // entries.rows[i].doc.syncStatus = false;
obj.add(JSON.parse(JSON.stringify(entries.rows[i].doc)));
}
}
diff --git a/src/store/PosStore/ItemStore.js b/src/store/PosStore/ItemStore.js
index 67c219a..bee3e31 100644
--- a/src/store/PosStore/ItemStore.js
+++ b/src/store/PosStore/ItemStore.js
@@ -24,6 +24,7 @@ export const Item = types
description: types.optional(types.string, ""),
soldBy: types.string,
price: types.optional(types.number, 0),
+ tax: types.optional(types.number, 0),
sku: types.optional(types.string, ""),
barcode: types.union(types.string, types.number),
colorAndShape: types.optional(types.string, ""),
@@ -155,6 +156,11 @@ const Store = types
}
}
},
+ resetLengths(obj) {
+ let objectLength = JSON.parse(self.categoryLengths);
+ objectLength = [];
+ self.categoryLengths = JSON.stringify(objectLength);
+ },
updateLengthObjects(obj) {
if (obj) {
let objectLength = JSON.parse(self.categoryLengths);
diff --git a/src/store/PosStore/PaymentStore.js b/src/store/PosStore/PaymentStore.js
index 93802fd..4345e5e 100644
--- a/src/store/PosStore/PaymentStore.js
+++ b/src/store/PosStore/PaymentStore.js
@@ -21,7 +21,7 @@ export const Payment = types
date: types.Date,
receipt: types.string,
paid: types.number,
- type: types.enumeration("Type", ["Cash", "Card", "Visa", "Amex", "Sapn"]),
+ type: types.optional(types.string, ""),
deviceId: types.optional(types.string, DeviceInfo.getDeviceId()),
dateUpdated: types.optional(types.Date, Date.now),
syncStatus: types.optional(types.boolean, false),
@@ -52,6 +52,19 @@ const PaymentStore = types
const paid = self.defaultPayment.paid;
return paid - netTotal;
},
+ get amountChangeRoundOff() {
+ const netTotal =
+ parseFloat(self.paymentReceipt.netTotal, 10) -
+ parseInt(self.paymentReceipt.netTotal, 10);
+
+ const paid = self.defaultPayment.paid;
+ return (
+ paid -
+ (netTotal < 0.5
+ ? parseInt(self.paymentReceipt.netTotal, 10)
+ : parseFloat(self.paymentReceipt.netTotal, 10))
+ );
+ },
}))
.actions(self => ({
initSync(session) {
diff --git a/src/store/PosStore/PrinterStore.js b/src/store/PosStore/PrinterStore.js
index 5ba5147..3627822 100644
--- a/src/store/PosStore/PrinterStore.js
+++ b/src/store/PosStore/PrinterStore.js
@@ -72,11 +72,19 @@ export const Company = types
name: types.string,
header: types.string,
footer: types.string,
+ changeNoReceipts: types.string,
companyLanguage: types.string,
tax: types.optional(types.string, "0"),
countryCode: types.optional(types.string, "PHP"),
currencyDisable: types.optional(types.boolean, false),
+ enableOverallTax: types.optional(types.boolean, false),
+ smallSizeIcon: types.optional(types.boolean, false),
+ mediumSizeIcon: types.optional(types.boolean, false),
+ largeSizeIcon: types.optional(types.boolean, true),
hideCategory: types.optional(types.boolean, false),
+ multipleMop: types.optional(types.boolean, false),
+ hideMenuBar: types.optional(types.boolean, false),
+ allowRoundOff: types.optional(types.boolean, false),
})
.preProcessSnapshot(snapshot => assignUUID(snapshot, "Company"))
.actions(self => ({
@@ -333,29 +341,60 @@ const Store = types
if (!entries.rows[i].doc.companyLanguage) {
entries.rows[i].doc.companyLanguage = "en";
}
+ if (!entries.rows[i].doc.changeNoReceipts) {
+ entries.rows[i].doc.changeNoReceipts = "1";
+ }
+ if (!entries.rows[i].doc.smallSizeIcon) {
+ entries.rows[i].doc.smallSizeIcon = false;
+ }
+ if (!entries.rows[i].doc.mediumSizeIcon) {
+ entries.rows[i].doc.mediumSizeIcon = false;
+ }
+ if (!entries.rows[i].doc.largeSizeIcon) {
+ entries.rows[i].doc.largeSizeIcon = false;
+ }
+ if (!entries.rows[i].doc.multipleMop) {
+ entries.rows[i].doc.multipleMop = false;
+ }
+ if (!entries.rows[i].doc.allowRoundOff) {
+ entries.rows[i].doc.allowRoundOff = false;
+ }
+
self.addCompany(JSON.parse(JSON.stringify(entries.rows[i].doc)));
}
}
if (entries.rows.length <= 0) {
self.addCompany({
name: "",
+ changeNoReceipts: "1",
header: "",
footer: "",
companyLanguage: "en",
tax: "0",
countryCode: "PHP",
currencyDisable: false,
+ smallSizeIcon: false,
+ mediumSizeIcon: false,
+ largeSizeIcon: true,
+ multipleMop: false,
+ allowRoundOff: false,
});
}
} else {
self.addCompany({
name: "",
+ changeNoReceipts: "1",
header: "",
companyLanguage: "en",
footer: "",
tax: "0",
countryCode: "PHP",
currencyDisable: false,
+ smallSizeIcon: false,
+ mediumSizeIcon: false,
+ largeSizeIcon: true,
+ multipleMop: false,
+ allowRoundOff: false,
});
}
});
diff --git a/src/store/PosStore/ReceiptStore.js b/src/store/PosStore/ReceiptStore.js
index d7e9796..231f279 100644
--- a/src/store/PosStore/ReceiptStore.js
+++ b/src/store/PosStore/ReceiptStore.js
@@ -26,6 +26,7 @@ export const ReceiptLine = types
qty: types.number,
commission_details: types.optional(types.string, "[]"),
discount_rate: types.optional(types.number, 0),
+ tax: types.optional(types.number, 0),
discountType: types.optional(types.string, "percentage"),
})
.preProcessSnapshot(snapshot => assignUUID(snapshot, "ReceiptLine"))
@@ -43,6 +44,9 @@ export const ReceiptLine = types
}
return self.price * self.qty;
},
+ get tax_total() {
+ return self.total * (self.tax / 100);
+ },
}))
.actions(self => ({
setQuantity(qty) {
@@ -98,11 +102,13 @@ export const Receipt = types
receiptNumber: types.optional(types.number, 0),
discountType: types.optional(types.string, "percentage"),
taxesValue: types.optional(types.string, ""),
+
taxesAmount: types.optional(types.number, 0),
shift: types.optional(types.string, ""),
deviceId: types.optional(types.string, DeviceInfo.getDeviceId()),
dateUpdated: types.optional(types.Date, Date.now),
syncStatus: types.optional(types.boolean, false),
+ roundOff: types.optional(types.boolean, false),
attendant: types.optional(types.string, ""),
orderType: types.optional(
types.enumeration("OrderType", [
@@ -164,8 +170,26 @@ export const Receipt = types
if (netTotal <= 0) {
netTotal = 0;
}
+
return netTotal;
},
+ get netTotalRoundOff() {
+ let discountValue = self.discountValue;
+ if (self.discountType === "percentage") {
+ discountValue = discountValue * self.grandTotal;
+ }
+
+ let netTotal = self.grandTotal - discountValue;
+
+ if (netTotal <= 0) {
+ netTotal = 0;
+ }
+ let roundoff_check =
+ parseFloat(netTotal, 10).toFixed(2) - parseInt(netTotal, 10);
+ return roundoff_check < 0.5
+ ? parseInt(netTotal, 10)
+ : parseFloat(netTotal, 10).toFixed(2);
+ },
get grandQuantity() {
if (self.lines.length !== 0) {
let total = 0;
@@ -187,6 +211,20 @@ export const Receipt = types
}
return 0;
},
+ get subtotalRoundOff() {
+ if (self.lines.length !== 0) {
+ let total = 0;
+ for (let i = 0; i < self.lines.length; i++) {
+ total = total + self.lines[i].total;
+ }
+ let roundoff_check =
+ parseFloat(total, 10).toFixed(2) - parseInt(total, 10);
+ return roundoff_check < 0.5
+ ? parseInt(total, 10)
+ : parseFloat(total, 10).toFixed(2);
+ }
+ return 0;
+ },
get get_tax_total() {
if (self.lines.length !== 0) {
let total = 0;
@@ -198,6 +236,17 @@ export const Receipt = types
}
return 0;
},
+ get get_tax_total_based_on_each_item() {
+ if (self.lines.length !== 0) {
+ let total = 0;
+ for (let i = 0; i < self.lines.length; i++) {
+ total = total + self.lines[i].tax_total;
+ }
+
+ return total;
+ }
+ return 0;
+ },
get linesLength() {
return self.lines.length;
},
@@ -255,6 +304,9 @@ export const Receipt = types
setOrderType(orderType) {
self.orderType = orderType;
},
+ setRoundOff(roundOff) {
+ self.roundOff = roundOff;
+ },
add(line, isStackItem) {
let resLine = null;
@@ -341,9 +393,10 @@ export const Receipt = types
// Yay!
self.lines.splice(0, self.lines.length);
},
- completed(attendant) {
+ setAttendant(attendant) {
self.attendant = attendant;
-
+ },
+ completed(attendant) {
self.status = "completed";
},
cancelled(obj) {
@@ -358,6 +411,12 @@ export const Receipt = types
// self.dateUpdate = Date.now;
self.syncStatus = true;
},
+ setCancel(reason) {
+ self.reason = reason;
+ self.status = "cancelled";
+ self.dateUpdated = Date.now();
+ self.syncStatus = false;
+ },
}));
const Store = types
@@ -449,6 +508,7 @@ const Store = types
setReceipt(receipt) {
self.defaultReceipt = receipt;
},
+
async setDefaultCustomer() {
return await customerDB
.find({
@@ -538,7 +598,7 @@ const Store = types
},
currentReceipt(tax) {
- if (!self.defaultReceipt || self.defaultReceipt.status === "completed") {
+ if (!self.defaultReceipt) {
db
.find({
selector: {
@@ -630,7 +690,6 @@ const Store = types
if (result && result.docs.length > 0) {
for (let x = 0; x < result.docs.length; x++) {
const doc = result.docs[x];
-
const receiptObj = Receipt.create({
_id: doc._id,
date: Date.parse(new Date(doc.date).toDateString()),
diff --git a/src/store/PosStore/ShiftStore.js b/src/store/PosStore/ShiftStore.js
index 2371986..25d92bb 100644
--- a/src/store/PosStore/ShiftStore.js
+++ b/src/store/PosStore/ShiftStore.js
@@ -49,6 +49,8 @@ export const Shift = types
syncStatus: types.optional(types.boolean, false),
categories_total_amounts: types.optional(types.string, "[]"),
mop_total_amounts: types.optional(types.string, "[]"),
+ voided: types.optional(types.number, 0),
+ cancelled: types.optional(types.number, 0),
})
.preProcessSnapshot(snapshot => assignUUID(snapshot, "Shift"))
.views(self => ({
@@ -193,6 +195,13 @@ export const Shift = types
changeShort() {
self.short = 0;
},
+ receiptCancelled(cancelled) {
+ // self.voided = self.voided + 1;
+ self.cancelled = self.cancelled + parseFloat(cancelled);
+ },
+ orderVoid() {
+ self.voided = self.voided + 1;
+ },
changeValues(obj) {
self.beginning_cash += obj.beginning_cash;
self.ending_cash += obj.ending_cash;
@@ -295,6 +304,7 @@ const ShiftStore = types
},
setNewValues(obj) {
self.defaultShift.minusValues(obj);
+ self.defaultShift.receiptCancelled(obj.total);
},
findShift(id) {
return new Promise(function(resolve, reject) {
@@ -373,6 +383,8 @@ const ShiftStore = types
mop_total_amounts: doc.mop_total_amounts,
dateUpdated: Date.now(),
syncStatus: false,
+ voided: doc.voided,
+ cancelled: doc.cancelled,
});
Object.keys(doc.pays).map(key => {
@@ -407,6 +419,8 @@ const ShiftStore = types
mop_total_amounts: entries.rows[i].doc.mop_total_amounts,
dateUpdated: Date.now(),
syncStatus: false,
+ voided: entries.rows[i].doc.voided,
+ cancelled: entries.rows[i].doc.cancelled,
});
Object.keys(entries.rows[i].doc.pays).map(key => {
zReadingObj.addPay(entries.rows[i].doc.pays[key]);
@@ -451,7 +465,8 @@ const ShiftStore = types
status: report.status,
categories_total_amounts: report.categories_total_amounts,
mop_total_amounts: report.mop_total_amounts,
-
+ voided: report.voided,
+ cancelled: report.cancelled,
commissions: report.commissions,
reportType: report.reportType,
dateUpdated: report.dateUpdated,
diff --git a/src/store/PosStore/SyncStore.js b/src/store/PosStore/SyncStore.js
index 6d99a5f..c42bd05 100644
--- a/src/store/PosStore/SyncStore.js
+++ b/src/store/PosStore/SyncStore.js
@@ -1,14 +1,7 @@
import { types } from "mobx-state-tree";
import { openAndSyncDB, sync, saveSnapshotToDB } from "./DbFunctions";
import { assignUUID } from "./Utils";
-// let Item = openAndSyncDB("items");
-// let Category = openAndSyncDB("categories");
-// let Discount = openAndSyncDB("discounts");
-// let shiftDb = openAndSyncDB("categories");
-// let attendantDb = openAndSyncDB("categories");
-// let shiftReportDb = openAndSyncDB("categories");
-// let receiptDb = openAndSyncDB("categories");
-// let paymentDb = openAndSyncDB("categories");
+
let trash = openAndSyncDB("trash", true);
export const Trash = types
.model("Trash", {
diff --git a/src/store/PosStore/syncInBackground.js b/src/store/PosStore/syncInBackground.js
index a51909a..7aa37ef 100644
--- a/src/store/PosStore/syncInBackground.js
+++ b/src/store/PosStore/syncInBackground.js
@@ -7,7 +7,7 @@ import BackgroundJob from "react-native-background-job";
export function syncObjectValues(status, store, jobStatus) {
strings.setLanguage(currentLanguage().companyLanguage);
-
+ store.itemStore.resetLengths();
const { forceSync, selectedSync } = store.syncStore;
let syncStoreMethod = "";
@@ -28,9 +28,16 @@ export function syncObjectValues(status, store, jobStatus) {
const syncInfo = {
deviceId: store.stateStore.deviceId,
- url: protocol + store.printerStore.sync[0].url,
- user_name: store.printerStore.sync[0].user_name,
- password: store.printerStore.sync[0].password,
+ url:
+ store.printerStore.sync[0].url !== undefined
+ ? protocol + store.printerStore.sync[0].url
+ : "",
+ user_name: store.printerStore.sync[0].user_name
+ ? store.printerStore.sync[0].user_name
+ : "",
+ password: store.printerStore.sync[0].password
+ ? store.printerStore.sync[0].password
+ : "",
};
store.syncStore
@@ -53,6 +60,8 @@ export function syncObjectValues(status, store, jobStatus) {
await attendantSync(data[x], store);
} else if (table === "Company") {
await companySync(data[x], store);
+ } else if (table === "Wallet") {
+ await walletSync(data[x], store);
}
}
@@ -69,27 +78,30 @@ export function syncObjectValues(status, store, jobStatus) {
}
}
await changeSyncStatusValue(result, store);
-
+ await category_lengths(store);
if (!jobStatus) {
- Toast.show({
- text: strings.SyncSuccessful,
- duration: 3000,
- });
- store.stateStore.setIsNotSyncing();
+ setTimeout(() => {
+ Toast.show({
+ text: strings.SyncSuccessful + ". Please restart TailPOS",
+ duration: 30000,
+ });
+ store.stateStore.setIsNotSyncing();
+ }, 10000);
}
BackgroundJob.cancel({ jobKey: "AutomaticSync" });
});
} else {
if (!jobStatus) {
- Toast.show({
- text: strings.AlreadyUpToDate,
- type: "danger",
- duration: 3000,
- });
- store.stateStore.setIsNotSyncing();
+ setTimeout(() => {
+ Toast.show({
+ text: strings.AlreadyUpToDate,
+ type: "danger",
+ duration: 3000,
+ });
+ store.stateStore.setIsNotSyncing();
+ }, 10000);
}
-
BackgroundJob.cancel({ jobKey: "AutomaticSync" });
}
});
@@ -104,7 +116,6 @@ export async function itemSync(itemObject, store) {
);
if (categoryIds) {
categoryId = categoryIds._id;
- store.itemStore.updateLengthObjects(categoryIds._id);
}
} else {
categoryId = "No Category";
@@ -123,6 +134,10 @@ export async function itemSync(itemObject, store) {
itemObject.syncObject.standard_rate !== null
? itemObject.syncObject.standard_rate
: 0,
+ tax:
+ itemObject.syncObject.tax_rate !== null
+ ? itemObject.syncObject.tax_rate
+ : 0,
sku: itemObject.syncObject.sku !== null ? itemObject.syncObject.sku : "",
barcode:
itemObject.syncObject.barcode === null ||
@@ -159,6 +174,7 @@ export async function itemSync(itemObject, store) {
});
} else {
var objecct_to_add = {
+ _id: itemObject.syncObject.id,
name:
itemObject.syncObject.name !== null ? itemObject.syncObject.name : "",
description:
@@ -175,6 +191,10 @@ export async function itemSync(itemObject, store) {
itemObject.syncObject.standard_rate !== null
? itemObject.syncObject.standard_rate
: 0,
+ tax:
+ itemObject.syncObject.tax_rate !== null
+ ? itemObject.syncObject.tax_rate
+ : 0,
sku: itemObject.syncObject.sku !== null ? itemObject.syncObject.sku : "",
barcode:
itemObject.syncObject.barcode !== null &&
@@ -206,20 +226,13 @@ export async function itemSync(itemObject, store) {
category: categoryId,
taxes: "[]",
dateUpdated: Date.now(),
- syncStatus: itemObject.syncObject.id !== null ? true : false,
+ syncStatus: itemObject.syncObject.id !== null,
};
itemObject.syncObject.id !== null
? (objecct_to_add._id = itemObject.syncObject.id)
: null;
store.itemStore.add(objecct_to_add);
- itemObject.syncObject.category !== null
- ? store.itemStore.updateLengthObjects(itemObject.syncObject.category)
- : null;
- itemObject.syncObject.category !== null ||
- itemObject.syncObject.category === null
- ? store.itemStore.updateLength()
- : null;
}
}
@@ -405,7 +418,47 @@ export async function customerSync(customerObject, store) {
}
}
}
+export async function walletSync(walletObject, store) {
+ if (walletObject.syncObject.id !== null) {
+ const walletObjectResult = await store.walletStore.find(
+ walletObject.syncObject.id,
+ );
+ if (walletObjectResult) {
+ walletObjectResult.edit({
+ _id: walletObjectResult.syncObject.id,
+ wallet_card_number:
+ walletObjectResult.syncObject.wallet_card_number !== null
+ ? walletObjectResult.syncObject.wallet_card_number
+ : "",
+ prepaid_balance:
+ walletObjectResult.syncObject.prepaid_balance !== null
+ ? walletObjectResult.syncObject.prepaid_balance
+ : 0,
+ credit_limit:
+ walletObjectResult.syncObject.credit_limit !== null
+ ? walletObjectResult.syncObject.credit_limit
+ : 0,
+ });
+ } else {
+ store.walletStore.add({
+ _id: walletObject.syncObject.id,
+ wallet_card_number:
+ walletObject.syncObject.wallet_card_number !== null
+ ? walletObject.syncObject.wallet_card_number
+ : "",
+ prepaid_balance:
+ walletObject.syncObject.prepaid_balance !== null
+ ? walletObject.syncObject.prepaid_balance
+ : 0,
+ credit_limit:
+ walletObject.syncObject.credit_limit !== null
+ ? walletObject.syncObject.credit_limit
+ : 0,
+ });
+ }
+ }
+}
export async function companySync(companyObject, store) {
const companyObjectResult = await store.printerStore.findCompany(
store.printerStore.companySettings[0]._id,
@@ -549,3 +602,6 @@ export async function deleteRecords(deletedObject, store) {
}
}
}
+export async function category_lengths(props) {
+ await props.itemStore.getLengthItemsFromDb();
+}
diff --git a/src/store/StateStore/DefaultValues.js b/src/store/StateStore/DefaultValues.js
index ec4f836..03c9ec9 100644
--- a/src/store/StateStore/DefaultValues.js
+++ b/src/store/StateStore/DefaultValues.js
@@ -22,6 +22,7 @@ export const sales = {
fetching: false,
addReceiptLineStatus: false,
confirmOrder: false,
+ confirmation: false,
commissionArray: JSON.stringify([]),
};
export const listing = {
@@ -54,6 +55,7 @@ export const payment = {
customerName: "",
customerEmail: "",
customerPhoneNumber: "",
+ walletCardNumber: "",
customerNotes: "",
arrayObjects: JSON.stringify([]),
};
@@ -63,6 +65,13 @@ export const settings = {
connectionStatus: "Not Connected",
currentAddress: "",
companyName: "",
+ changeNoReceipts: "1",
+ smallSizeIcon: false,
+ mediumSizeIcon: false,
+ largeSizeIcon: true,
+ multipleMop: false,
+ allowRoundOff: false,
+ hideMenuBar: false,
tax: "0",
companyHeader: "",
companyFooter: "",
diff --git a/src/store/StateStore/Models.js b/src/store/StateStore/Models.js
index f042813..48b3e7f 100644
--- a/src/store/StateStore/Models.js
+++ b/src/store/StateStore/Models.js
@@ -23,6 +23,7 @@ export const ModelSales = {
discountSelectionStatus: types.optional(types.boolean, true),
fetching: types.optional(types.boolean, false),
confirmOrder: types.optional(types.boolean, false),
+ confirmation: types.optional(types.boolean, false),
addReceiptLineStatus: types.optional(types.boolean, false),
};
export const ModelListing = {
@@ -54,6 +55,7 @@ export const ModelPayment = {
modalVisible: types.optional(types.boolean, false),
customerName: types.optional(types.string, ""),
customerEmail: types.optional(types.string, ""),
+ walletCardNumber: types.optional(types.string, ""),
customerPhoneNumber: types.optional(types.string, ""),
customerNotes: types.optional(types.string, ""),
arrayObjects: types.optional(types.string, "[]"),
@@ -64,11 +66,18 @@ export const ModelSettings = {
connectionStatus: types.optional(types.string, "Not Connected"),
currentAddress: types.optional(types.string, ""),
companyName: types.optional(types.string, ""),
+ changeNoReceipts: types.optional(types.string, ""),
tax: types.optional(types.string, "0"),
companyHeader: types.optional(types.string, ""),
companyFooter: types.optional(types.string, ""),
companyCurrency: types.optional(types.string, ""),
checkBoxBluetoothValue: types.optional(types.boolean, false),
+ smallSizeIcon: types.optional(types.boolean, false),
+ mediumSizeIcon: types.optional(types.boolean, false),
+ largeSizeIcon: types.optional(types.boolean, true),
+ multipleMop: types.optional(types.boolean, false),
+ allowRoundOff: types.optional(types.boolean, false),
+ hideMenuBar: types.optional(types.boolean, false),
checkBoxValue: types.optional(types.string, ""),
attendants: types.optional(types.string, "[]"),
// attendantsInfo: {},
diff --git a/src/store/StateStore/StateStore.js b/src/store/StateStore/StateStore.js
index b135c7a..d02a061 100644
--- a/src/store/StateStore/StateStore.js
+++ b/src/store/StateStore/StateStore.js
@@ -32,7 +32,16 @@ const StateStore = types
currentTable: types.optional(types.number, -1),
isViewingOrder: types.optional(types.boolean, false),
isLoadingOrder: types.optional(types.boolean, false),
-
+ currentConfirmation: types.optional(types.string, ""),
+ index_value: types.optional(types.number, 0),
+ discount_string: types.optional(types.string, "{}"),
+ receipt_summary: types.optional(types.string, "{}"),
+ scanned_nfc: types.optional(types.string, "{}"),
+ payment_types: types.optional(types.string, "[]"),
+ payment_amount: types.optional(types.string, "0"),
+ balance: types.optional(types.string, "0"),
+ customers_pin: types.optional(types.boolean, false),
+ customers_pin_value: types.optional(types.string, ""),
// Settings
queueHost: types.optional(types.string, ""),
hasTailOrder: types.optional(types.boolean, false),
@@ -40,6 +49,7 @@ const StateStore = types
useDescription: types.optional(types.boolean, false),
isHttps: types.optional(types.boolean, false),
isCurrencyDisabled: types.optional(types.boolean, false),
+ enableOverallTax: types.optional(types.boolean, false),
deviceId: types.optional(types.string, ""),
isStackItem: types.optional(types.boolean, false),
@@ -76,6 +86,21 @@ const StateStore = types
});
});
},
+ updateScannedNfc(key, value) {
+ let scanned_nfc = JSON.parse(self.scanned_nfc);
+
+ scanned_nfc[key] = value;
+ self.scanned_nfc = JSON.stringify(scanned_nfc);
+ },
+ is_customers_pin() {
+ self.customers_pin = true;
+ },
+ is_not_customers_pin() {
+ self.customers_pin = true;
+ },
+ set_receipt_summary(data) {
+ self.receipt_summary = data;
+ },
setDefaultValues(containerName, objectValue) {
let containerNameValue = "";
if (containerName === "Sales") {
@@ -117,9 +142,57 @@ const StateStore = types
}
});
},
+ resetPaymentTypes() {
+ self.payment_types = "[]";
+ },
+
+ resetScannedNfc() {
+ self.scanned_nfc = "{}";
+ },
+ addPaymentTypes(obj) {
+ let payment_types = JSON.parse(self.payment_types);
+ payment_types.push(obj);
+ self.payment_types = JSON.stringify(payment_types);
+ },
+ updatePaymentType(obj) {
+ if (obj) {
+ let objectLength = JSON.parse(self.payment_types);
+ let exists = false;
+ for (let i = 0; i < objectLength.length; i += 1) {
+ if (obj.type === objectLength[i].type) {
+ objectLength[i].amount = obj.amount;
+ exists = true;
+ }
+ }
+ if (!exists) {
+ self.addPaymentTypes({
+ type: obj.type,
+ amount: obj.amount,
+ });
+ } else {
+ self.payment_types = JSON.stringify(objectLength);
+ }
+ }
+ },
+ removePaymentType() {
+ let objectLength = JSON.parse(self.payment_types);
+ let filtered_items = objectLength.filter(
+ payment_type => payment_type.type !== self.payment_state[0].selected,
+ );
+ self.payment_types = JSON.stringify(filtered_items);
+ },
setPaymentValue(value) {
self.payment_value = value;
},
+ set_customers_pin(value) {
+ self.customers_pin_value = value;
+ },
+ setMopAmount(value) {
+ self.payment_amount = value;
+ },
+ setBalance(value) {
+ self.balance = value;
+ },
setAmountDue(value) {
self.amount_due = value;
},
@@ -129,6 +202,12 @@ const StateStore = types
setLoadingOrder(isLoadingOrder) {
self.isLoadingOrder = isLoadingOrder;
},
+ changeConfirmation(currentConfirmation) {
+ self.currentConfirmation = currentConfirmation;
+ },
+ changeIndex(index) {
+ self.index_value = index;
+ },
setOrders(orders) {
self.orders = orders;
},
@@ -141,6 +220,9 @@ const StateStore = types
setQueueHost(host) {
self.queueHost = host;
},
+ changeDiscountString(discount) {
+ self.discount_string = discount;
+ },
toggleTailOrder() {
self.hasTailOrder = !self.hasTailOrder;
},
@@ -192,6 +274,9 @@ const StateStore = types
toggleCurrencyDisabled() {
self.isCurrencyDisabled = !self.isCurrencyDisabled;
},
+ toggleEnableOverallTax() {
+ self.enableOverallTax = !self.enableOverallTax;
+ },
setDeviceId(deviceId) {
self.deviceId = deviceId;
},
@@ -201,6 +286,9 @@ const StateStore = types
changeCompanyCheckBox(isCurrencyDisabled) {
self.isCurrencyDisabled = isCurrencyDisabled;
},
+ changeOverallTax(overallTax) {
+ self.enableOverallTax = overallTax;
+ },
}));
const Store = StateStore.create({});
diff --git a/src/stories/components/AttendantsFormComponent.js b/src/stories/components/AttendantsFormComponent.js
index 2ad4cfd..5249c62 100644
--- a/src/stories/components/AttendantsFormComponent.js
+++ b/src/stories/components/AttendantsFormComponent.js
@@ -20,6 +20,7 @@ class AddAttendantComponent extends React.Component {
status: "Save Attendant",
role: "Owner",
canLogin: false,
+ canApprove: false,
commission: "",
};
}
@@ -59,6 +60,7 @@ class AddAttendantComponent extends React.Component {
securityPinStatus: true,
securityConfirmPinStatus: true,
canLogin: attendantInfo.canLogin,
+ canApprove: attendantInfo.canApprove,
commission: attendantInfo.commission.toString(),
});
} else {
@@ -72,6 +74,7 @@ class AddAttendantComponent extends React.Component {
status: "Save Attendant",
role: "Owner",
canLogin: false,
+ canApprove: false,
commission: "",
});
}
@@ -111,6 +114,10 @@ class AddAttendantComponent extends React.Component {
const { canLogin } = this.state;
this.setState({ canLogin: !canLogin });
};
+ toggleCanApprove = () => {
+ const { canApprove } = this.state;
+ this.setState({ canApprove: !canApprove });
+ };
onPress = () => {
const { status } = this.state;
@@ -201,7 +208,7 @@ class AddAttendantComponent extends React.Component {
strings.setLanguage(currentLanguage().companyLanguage);
const { rolesData } = this.props;
- const { attendantName, role, canLogin } = this.state;
+ const { attendantName, role, canLogin, canApprove } = this.state;
const Roles = rolesData.map(this.renderRoles);
@@ -234,8 +241,17 @@ class AddAttendantComponent extends React.Component {
/>
{strings.CanLogin}
- {canLogin ? this.renderPin() : null}
- {canLogin ? this.renderConfirmPin() : null}
+
+
+ Can Approve
+
+ {canLogin || canApprove ? this.renderPin() : null}
+ {canLogin || canApprove ? this.renderConfirmPin() : null}
diff --git a/src/stories/components/CategoriesComponent.js b/src/stories/components/CategoriesComponent.js
index dfdfc45..34a3793 100644
--- a/src/stories/components/CategoriesComponent.js
+++ b/src/stories/components/CategoriesComponent.js
@@ -1,6 +1,7 @@
import * as React from "react";
import { FlatList, View, Dimensions } from "react-native";
import { Text, Button } from "native-base";
+
import { currentLanguage } from "../../translations/CurrentLanguage";
import translation from "../.././translations/translation";
@@ -44,7 +45,7 @@ export default class CategoriesComponent extends React.PureComponent {
style={{
height: this.props.bluetoothStatus
? Dimensions.get("window").height * 0.75
- : Dimensions.get("window").height * 0.85,
+ : Dimensions.get("window").height * 1.05,
}}
>
);
}
-
return (
- {strings.ConfirmOrder}
+ {strings.ConfirmOrder}
);
};
@@ -88,6 +87,9 @@ const styles = StyleSheet.create({
paddingRight: 10,
alignSelf: "center",
},
+ confirmButton: {
+ fontSize: Dimensions.get("window").width * 0.01,
+ },
});
export default GrandTotalComponent;
diff --git a/src/stories/components/ModalKeypadComponent.js b/src/stories/components/ModalKeypadComponent.js
index 0155c10..96bedbe 100644
--- a/src/stories/components/ModalKeypadComponent.js
+++ b/src/stories/components/ModalKeypadComponent.js
@@ -44,7 +44,11 @@ export default class ModalKeypadComponent extends React.PureComponent {
-
+ {"noPeriod" in this.props ? (
+ null} />
+ ) : (
+
+ )}
diff --git a/src/stories/components/MoreSettingsComponent.js b/src/stories/components/MoreSettingsComponent.js
new file mode 100644
index 0000000..a1af2cf
--- /dev/null
+++ b/src/stories/components/MoreSettingsComponent.js
@@ -0,0 +1,155 @@
+import * as React from "react";
+import { Dimensions, View, StyleSheet } from "react-native";
+import { Text, Card, CardItem } from "native-base";
+import { Col, Grid } from "react-native-easy-grid";
+import { currentLanguage } from "../../translations/CurrentLanguage";
+
+import EditInput from "./EditInputComponent";
+import EditCheckBox from "./EditCheckBoxComponent";
+import translation from "../.././translations/translation";
+import LocalizedStrings from "react-native-localization";
+let strings = new LocalizedStrings(translation);
+class MoreSettingsComponent extends React.PureComponent {
+ render() {
+ const {
+ toggleItemSize,
+ toggleMultipleMop,
+ toggleAllowRoundOff,
+ toggleHideMenuBar,
+ } = this.props;
+ const {
+ smallSizeIcon,
+ mediumSizeIcon,
+ largeSizeIcon,
+ multipleMop,
+ allowRoundOff,
+ hideMenuBar,
+ } = this.props.values;
+ strings.setLanguage(currentLanguage().companyLanguage);
+
+ return (
+
+
+
+
+
+ More Settings
+
+
+
+
+
+
+
+
+ toggleMultipleMop("Medium")}
+ />
+
+
+
+
+
+
+
+
+
+ Item Icon Size
+
+
+ toggleItemSize("Small")}
+ />
+
+
+ toggleItemSize("Medium")}
+ />
+
+
+ toggleItemSize("Large")}
+ />
+
+
+
+ );
+ }
+}
+const styles = StyleSheet.create({
+ card: {
+ width: "100%",
+ alignSelf: "center",
+ },
+ cardItem: {
+ marginBottom: 15,
+ backgroundColor: "#4b4c9d",
+ },
+ col: {
+ alignSelf: "center",
+ },
+ titleText: {
+ color: "white",
+ fontSize: Dimensions.get("window").width * 0.02,
+ },
+ icon: {
+ color: "white",
+ marginLeft: 10,
+ },
+ viewRight: {
+ flexDirection: "row",
+ alignSelf: "flex-end",
+ },
+ cardItemHelp: {
+ borderColor: "gray",
+ borderBottomWidth: 0.5,
+ },
+ cardItemText: {
+ marginLeft: 10,
+ fontWeight: "bold",
+ color: "gray",
+ },
+ cardItemView: {
+ width: "50%",
+ marginLeft: 3,
+ },
+ cardItemViewTextAreaTax: {
+ width: "50%",
+ marginLeft: 3,
+ },
+ cardItemViewTextArea: {
+ width: "60%",
+ },
+ pickerView: {
+ borderWidth: 1,
+ borderColor: "#cfcfcf",
+ },
+ picker: {
+ width: "100%",
+ },
+ text: {
+ fontWeight: "bold",
+ },
+});
+
+export default MoreSettingsComponent;
diff --git a/src/stories/components/NumberKeysComponent.js b/src/stories/components/NumberKeysComponent.js
index 52c1c09..3b5ed47 100644
--- a/src/stories/components/NumberKeysComponent.js
+++ b/src/stories/components/NumberKeysComponent.js
@@ -1,6 +1,6 @@
import * as React from "react";
import { Dimensions, Text, FlatList } from "react-native";
-import { Form, Item, Button, Input } from "native-base";
+import { Form, Item, Button, Input, View } from "native-base";
import Icon from "react-native-vector-icons/FontAwesome";
var MoneyCurrency = require("money-currencies");
import { currentLanguage } from "../../translations/CurrentLanguage";
@@ -23,7 +23,6 @@ export default class NumberKeysComponent extends React.PureComponent {
};
render() {
strings.setLanguage(currentLanguage().companyLanguage);
-
let mc = new MoneyCurrency(
this.props.currency ? this.props.currency : "PHP",
);
@@ -42,47 +41,77 @@ export default class NumberKeysComponent extends React.PureComponent {
underlineColorAndroid="transparent"
/>
+
-
-
-
- {strings.Pay}
-
-
+
+ {this.props.mop === "Wallet" ? (
+
+ {!("customer" in this.props.scanned_nfc) ||
+ !("attendant" in this.props.scanned_nfc) ? (
+
+ Waiting for nfc card...
+
+ ) : (
+
+ Please use this keypad to enter customers pin
+
+ )}
+
+ ) : (
+
+
+
+ {strings.Pay}
+
+
+ )}
);
}
diff --git a/src/stories/components/OrderItemComponent.js b/src/stories/components/OrderItemComponent.js
index f1bb001..24b8a97 100644
--- a/src/stories/components/OrderItemComponent.js
+++ b/src/stories/components/OrderItemComponent.js
@@ -13,44 +13,90 @@ class OrderItemComponent extends React.PureComponent {
render() {
strings.setLanguage(currentLanguage().companyLanguage);
- const { id, tableNo, isTakeAway } = this.props;
-
+ const { id, tableNo, isTakeAway, company, type } = this.props;
+ const size = company.smallSizeIcon
+ ? styles.smallSizeIcon
+ : company.mediumSizeIcon
+ ? styles.mediumSizeIcon
+ : styles.largeSizeIcon;
+ const text = company.smallSizeIcon
+ ? styles.smalltext
+ : company.mediumSizeIcon
+ ? styles.mediumtext
+ : styles.largetext;
+ const orderText = company.smallSizeIcon
+ ? styles.smallOrderText
+ : company.mediumSizeIcon
+ ? styles.mediumOrderText
+ : styles.largeOrderText;
return (
-
-
+
+
[{strings.ORDER}-{id}]
-
- {strings.TableNo} {tableNo}
+
+ {type} {strings.TableNo} {tableNo}
);
}
}
-
const styles = StyleSheet.create({
view: {
margin: 15,
- width: 180,
- height: 180,
borderRadius: 180 / 2,
justifyContent: "center",
backgroundColor: "#afafaf",
},
+ largeSizeIcon: {
+ width: 160,
+ height: 160,
+ },
+ mediumSizeIcon: {
+ width: 110,
+ height: 110,
+ },
+ smallSizeIcon: {
+ width: 80,
+ height: 80,
+ },
takeAwayView: {
backgroundColor: "#ffb020",
},
- text: {
+ //SMALL
+ smalltext: {
+ fontSize: 13,
+ fontWeight: "bold",
+ textAlign: "center",
+ },
+ smallOrderText: {
+ fontSize: 12,
+ fontWeight: "bold",
+ textAlign: "center",
+ },
+ //MEDIUM
+ mediumtext: {
+ fontSize: 17,
+ fontWeight: "bold",
+ textAlign: "center",
+ },
+ mediumOrderText: {
+ fontSize: 15,
+ fontWeight: "bold",
+ textAlign: "center",
+ },
+ //LARGE
+ largetext: {
fontSize: 21,
fontWeight: "bold",
textAlign: "center",
},
- orderText: {
+ largeOrderText: {
fontSize: 18,
fontWeight: "bold",
textAlign: "center",
diff --git a/src/stories/components/PrinterComponent.js b/src/stories/components/PrinterComponent.js
index 3e487ad..e9dd48a 100644
--- a/src/stories/components/PrinterComponent.js
+++ b/src/stories/components/PrinterComponent.js
@@ -30,7 +30,7 @@ const PrinterComponent = props => {
const connectionStatus = (
- {props.connection ? strings.Online : props.connectionStatus}
+ {props.connection ? "Online" : props.connectionStatus}
);
diff --git a/src/stories/components/QuantityModalComponent.js b/src/stories/components/QuantityModalComponent.js
index 618d565..7b2d0f5 100644
--- a/src/stories/components/QuantityModalComponent.js
+++ b/src/stories/components/QuantityModalComponent.js
@@ -470,16 +470,7 @@ export default class QuantityModalComponent extends React.Component {
this.props.onSubmit(this.state);
}}
>
-
- {strings.Set}{" "}
- {this.state.status === "Qty"
- ? "quantity"
- : this.state.status === "Price"
- ? "price"
- : this.state.status === "Commission"
- ? "commission"
- : ""}
-
+ Edit Transaction
diff --git a/src/stories/components/SingleReportComponent.js b/src/stories/components/SingleReportComponent.js
index 1365ff6..2752efd 100644
--- a/src/stories/components/SingleReportComponent.js
+++ b/src/stories/components/SingleReportComponent.js
@@ -10,6 +10,7 @@ let MoneyCurrency = require("money-currencies");
import translation from "../.././translations/translation";
import LocalizedStrings from "react-native-localization";
let strings = new LocalizedStrings(translation);
+
const SingleReportComponent = props => {
strings.setLanguage(currentLanguage().companyLanguage);
const categoryAmounts = JSON.parse(props.report.categories_total_amounts).map(
@@ -303,6 +304,28 @@ const SingleReportComponent = props => {
+
+
+ Cancelled
+
+
+
+ {props.isCurrencyDisabled
+ ? formatNumber(props.report.cancelled)
+ : new MoneyCurrency(
+ props.currency ? props.currency : "PHP",
+ ).moneyFormat(formatNumber(props.report.cancelled))}
+
+
+
+
+
+ Voided
+
+
+ {props.report.voided}
+
+
diff --git a/src/stories/components/SummaryModalComponent.js b/src/stories/components/SummaryModalComponent.js
index eb2dd2a..8fc1e34 100644
--- a/src/stories/components/SummaryModalComponent.js
+++ b/src/stories/components/SummaryModalComponent.js
@@ -97,11 +97,20 @@ export default class SummaryModalComponent extends React.Component {
- {mc.moneyFormat(
- formatNumber(
- parseFloat(this.props.details.get_tax_total),
- ),
- )}
+ {this.props.enableOverallTax
+ ? mc.moneyFormat(
+ formatNumber(
+ parseFloat(this.props.details.get_tax_total),
+ ),
+ )
+ : mc.moneyFormat(
+ formatNumber(
+ parseFloat(
+ this.props.details
+ .get_tax_total_based_on_each_item,
+ ),
+ ),
+ )}
diff --git a/src/stories/components/TabComponent.js b/src/stories/components/TabComponent.js
index c77c6b0..31a1e70 100644
--- a/src/stories/components/TabComponent.js
+++ b/src/stories/components/TabComponent.js
@@ -6,6 +6,7 @@ const TabComponent = props => (
props.onClick(index)}
diff --git a/src/stories/components/TotalLineComponent.js b/src/stories/components/TotalLineComponent.js
index fc80443..f41e1e7 100644
--- a/src/stories/components/TotalLineComponent.js
+++ b/src/stories/components/TotalLineComponent.js
@@ -25,7 +25,9 @@ const TotalLineComponent = props => (
{strings.Tax}{" "}
{parseFloat(props.receipt.taxesValue) > 0
- ? "(" + props.receipt.taxesValue.toString() + "%)"
+ ? props.enableOverallTax
+ ? "(" + props.receipt.taxesValue.toString() + "%)"
+ : ""
: ""}
diff --git a/src/stories/components/ViewOrderComponent.js b/src/stories/components/ViewOrderComponent.js
index c552174..4861e97 100644
--- a/src/stories/components/ViewOrderComponent.js
+++ b/src/stories/components/ViewOrderComponent.js
@@ -20,21 +20,25 @@ import LocalizedStrings from "react-native-localization";
let strings = new LocalizedStrings(translation);
class ViewOrderComponent extends React.PureComponent {
renderOrderItem = ({ item, index }) => {
- const { onTableClick, onTableLongPress } = this.props;
- return (
-
- );
- };
+ const { onTableClick, onTableLongPress, company } = this.props;
+ if (!item.is_fulfilled) {
+ return (
+
+ );
+ }
+ };
renderOrders() {
- const { orders } = this.props;
+ const { orders, company } = this.props;
if (orders.length === 0) {
return (
@@ -50,7 +54,7 @@ class ViewOrderComponent extends React.PureComponent {
return (
);
diff --git a/src/stories/screens/InputItem/frm.js b/src/stories/screens/InputItem/frm.js
index d9a97d7..d97d869 100644
--- a/src/stories/screens/InputItem/frm.js
+++ b/src/stories/screens/InputItem/frm.js
@@ -27,6 +27,9 @@ export default class Form {
const newPrice = isCurrencyDisabled ? price : price.slice(1);
this._setState({ price: newPrice });
};
+ onChangeTax = tax => {
+ this._setState({ tax: tax });
+ };
setSoldByEach = () => {
this._setState({ soldBy: "Each" });
};
diff --git a/src/stories/screens/InputItem/index.js b/src/stories/screens/InputItem/index.js
index a4a5c77..14dabda 100644
--- a/src/stories/screens/InputItem/index.js
+++ b/src/stories/screens/InputItem/index.js
@@ -38,24 +38,24 @@ export default class InputItem extends React.Component {
if (data) {
const priceCurrency = formatNumber(data.price);
-
this.setState({
name: data.name,
price: priceCurrency,
sku: data.sku,
+ tax: data.tax.toString(),
barcode: data.barcode,
category: data.category,
soldBy: data.soldBy,
colorAndShape: JSON.parse(data.colorAndShape),
});
}
-
if (dataDetails) {
const dataDupBarcode = JSON.parse(dataDetails);
this.setState({
name: dataDupBarcode.name,
price: dataDupBarcode.price.toString(),
sku: dataDupBarcode.sku,
+ tax: dataDupBarcode.tax,
barcode: dataDupBarcode.barcode,
category: dataDupBarcode.category,
soldBy: dataDupBarcode.soldBy,
@@ -70,6 +70,7 @@ export default class InputItem extends React.Component {
status: "item",
name: "",
price: "0.00",
+ tax: "0",
sku: "",
barcode: "",
category: "No Category",
@@ -219,6 +220,21 @@ export default class InputItem extends React.Component {
+
+
+
+
+ this.frm.onChangeTax(value)}
+ />
+
+
+
diff --git a/src/stories/screens/Payment/index.js b/src/stories/screens/Payment/index.js
index 8f45254..d89c7df 100644
--- a/src/stories/screens/Payment/index.js
+++ b/src/stories/screens/Payment/index.js
@@ -12,6 +12,8 @@ import {
Item,
Input,
Picker,
+ Textarea,
+ Text,
} from "native-base";
import { View, Alert, StyleSheet } from "react-native";
import { formatNumber } from "accounting-js";
@@ -34,13 +36,22 @@ const PAYMENT_ITEMS = [
,
,
,
+ ,
];
export default class Payment extends React.PureComponent {
onValueChange = text => {
this.props.onValueChange(text);
};
-
+ payment_type = () => {
+ const { paymentTypes } = this.props;
+ let payment_types_values = "";
+ for (let i = 0; i < paymentTypes.length; i += 1) {
+ payment_types_values +=
+ paymentTypes[i].type + " - " + paymentTypes[i].amount.toString() + "\n";
+ }
+ return payment_types_values;
+ };
onPay = () => {
Alert.alert(
strings.ConfirmPayment,
@@ -88,7 +99,10 @@ export default class Payment extends React.PureComponent {
let mc = new MoneyCurrency(
this.props.currency ? this.props.currency : "PHP",
);
- const amountValue = parseFloat(this.props.paymentValue);
+ const amountValue = this.props.settings_state.multipleMop
+ ? parseFloat(this.props.payment_amount_multiple)
+ : parseFloat(this.props.paymentValue);
+
const amountDue = parseFloat(this.props.amountDue);
let change = 0;
@@ -112,12 +126,36 @@ export default class Payment extends React.PureComponent {
+ {this.props.settings_state.multipleMop ? (
+
+
+
+
+
+
+ {PAYMENT_ITEMS}
+
+
+
+
+
+
+
+ ) : null}
@@ -152,18 +190,58 @@ export default class Payment extends React.PureComponent {
/>
- {this.renderCustomer()}
+ {/*{this.renderCustomer()}*/}
-
-
-
- {PAYMENT_ITEMS}
-
-
+ {this.props.settings_state.multipleMop ? (
+
+
+
+
+
+ -
+ 0
+ ? formatNumber(this.props.balance)
+ : formatNumber(0)
+ : formatNumber(this.props.balance) > 0
+ ? mc.moneyFormat(
+ formatNumber(this.props.balance),
+ )
+ : mc.moneyFormat(formatNumber(0))
+ }
+ />
+
+
+ ) : (
+
+
+
+ {PAYMENT_ITEMS}
+
+
+ )}
+ {this.props.values.selected === "Wallet" ? (
+ "customer" in this.props.scanned_nfc ? (
+
+
+
+ -
+
+
+
+
+
+ Proceed Wallet Transaction
+
+
+ Clear
+
+
+
+ ) : null
+ ) : null}
@@ -189,6 +298,21 @@ const styles = StyleSheet.create({
fontSize: 24,
color: "white",
},
+ button: {
+ marginTop: 5,
+ },
+ button1: {
+ marginTop: 5,
+ marginLeft: 10,
+ },
+ rightArrow: {
+ fontSize: 24,
+ color: "blue",
+ },
+ leftIcon: {
+ fontSize: 24,
+ color: "red",
+ },
headerTitle: {
marginLeft: "-35%",
fontWeight: "bold",
@@ -222,5 +346,6 @@ const styles = StyleSheet.create({
printerStyle: {
flex: 1,
marginBottom: 15,
+ marginLeft: 30,
},
});
diff --git a/src/stories/screens/ReceiptInfo/index.js b/src/stories/screens/ReceiptInfo/index.js
index e6f0067..ca24cd6 100644
--- a/src/stories/screens/ReceiptInfo/index.js
+++ b/src/stories/screens/ReceiptInfo/index.js
@@ -60,7 +60,11 @@ class ReceiptInfo extends React.Component {
customer={paymentCustomer.name}
discountName={paymentReceipt.discountName}
discountType={paymentReceipt.discountType}
- total={paymentReceipt.netTotal.toFixed(2)}
+ total={
+ paymentReceipt.roundOff
+ ? paymentReceipt.netTotalRoundOff
+ : paymentReceipt.netTotal.toFixed(2)
+ }
date={defaultPayment.date.toLocaleString()}
status={paymentReceipt.status}
reason={paymentReceipt.reason}
@@ -70,7 +74,11 @@ class ReceiptInfo extends React.Component {
discount={paymentReceipt.discounts.toFixed(2)}
receipt={this.props.receipt}
onReprint={values => this.props.onReprint(values)}
- change={this.props.paymentStore.amountChange.toFixed(2)}
+ change={
+ paymentReceipt.roundOff
+ ? this.props.paymentStore.amountChangeRoundOff
+ : this.props.paymentStore.amountChange.toFixed(2)
+ }
/>
diff --git a/src/stories/screens/Receipts/index.js b/src/stories/screens/Receipts/index.js
index 3421158..24c42b5 100644
--- a/src/stories/screens/Receipts/index.js
+++ b/src/stories/screens/Receipts/index.js
@@ -44,13 +44,14 @@ class Receipts extends React.PureComponent {
status={obj.status}
receipt={obj.receipt}
number={obj.receiptNumber}
- amount={obj.netTotal.toFixed(2)}
+ amount={
+ obj.roundOff ? obj.netTotalRoundOff : obj.netTotal.toFixed(2)
+ }
onPress={this.onReceiptClick}
/>
);
}
});
-
const ReceiptComponents =
this.props.receipts.length === 0 ? (
diff --git a/src/stories/screens/Sales/index.js b/src/stories/screens/Sales/index.js
index 2386cad..beacea9 100644
--- a/src/stories/screens/Sales/index.js
+++ b/src/stories/screens/Sales/index.js
@@ -11,6 +11,7 @@ import GrandTotalComponent from "@components/GrandTotalComponent";
import ViewOrderComponent from "../../components/ViewOrderComponent";
import ChangeTableComponent from "../../components/ChangeTableComponent";
+import CategoriesComponent from "@components/CategoriesComponent";
import Icon from "react-native-vector-icons/FontAwesome";
@@ -20,6 +21,10 @@ class Sales extends React.PureComponent {
onItemClick = index => this.props.onItemClick(index);
onReceiptLineDelete = index => this.props.onReceiptLineDelete(index);
onCategoryClick = (id, index) => this.props.onCategoryClick(id, index);
+ navigate = () => this.props.navigation.navigate("DrawerOpen");
+ onSearchClick = () => this.props.onSearchClick(true);
+ onCategoryEndReached = () => this.props.onEndReached("category");
+ onPressCategory = (id, index) => this.props.onCategoryClick(id, index);
renderOrder() {
const {
@@ -34,6 +39,7 @@ class Sales extends React.PureComponent {
onChangeTable,
onCloseTable,
onReprintOrder,
+ company,
} = this.props;
return inTableOptions ? (
@@ -46,6 +52,7 @@ class Sales extends React.PureComponent {
/>
) : (
-
-
- {searchStatus ? this.renderSearch() : this.renderHeader()}
-
-
-
-
-
-
-
+ {!company.hideMenuBar ? (
+
+
+ {searchStatus ? this.renderSearch() : this.renderHeader()}
+
+
+
+
+
+ ) : null}
+
+
+
{isViewingOrder ? (
this.renderOrder()
) : (
)}
+
+ {company.hideMenuBar ? (
+
+
+
+
+
+ ) : null}
-
-
+
+
+
+
+
+
+
+
diff --git a/src/stories/screens/SalesList/index.js b/src/stories/screens/SalesList/index.js
index ad10af2..7898d7b 100644
--- a/src/stories/screens/SalesList/index.js
+++ b/src/stories/screens/SalesList/index.js
@@ -10,6 +10,7 @@ import {
Row,
Grid,
Footer,
+ Button,
} from "native-base";
import Icon from "react-native-vector-icons/FontAwesome";
@@ -17,17 +18,10 @@ import Icon from "react-native-vector-icons/FontAwesome";
import SearchComponent from "@components/SearchComponent";
import EntriesComponent from "@components/EntriesComponent";
import BarcodeInput from "@components/BarcodeInputComponent";
-import CategoriesComponent from "@components/CategoriesComponent";
export default class SalesList extends React.PureComponent {
onPressItem = index => this.props.onItemClick(index);
- onPressCategory = (id, index) => this.props.onCategoryClick(id, index);
-
- onSearchClick = () => this.props.onSearchClick(true);
- navigate = () => this.props.navigation.navigate("DrawerOpen");
-
onItemEndReached = () => this.props.onEndReached("item");
- onCategoryEndReached = () => this.props.onEndReached("category");
ref = c => {
this.barcode = c;
@@ -52,14 +46,15 @@ export default class SalesList extends React.PureComponent {
return (
-
+
this.props.navigation.navigate("DrawerOpen")}
+ size={24}
color="white"
- style={styles.headerLeftIcon}
/>
-
+
@@ -89,7 +84,6 @@ export default class SalesList extends React.PureComponent {
render() {
const {
- searchStatus,
salesListStatus,
bluetoothStatus,
@@ -99,11 +93,6 @@ export default class SalesList extends React.PureComponent {
itemsLength,
onLongPressItem,
- // CategoriesComponent
- categoryData,
- categoryLengths,
- selectedCategoryIndex,
-
// TextInput
onChangeBarcodeScannerInput,
@@ -111,18 +100,20 @@ export default class SalesList extends React.PureComponent {
useDescription,
listStatus,
isCurrencyDisabled,
+ company,
} = this.props;
return (
{salesListStatus ? (
this.renderBarcode()
- ) : bluetoothStatus ? (
+ ) : (
-
-
-
+ {/**/}
+ {/**/}
+ {/**/}
-
+ {bluetoothStatus ? (
+
+ ) : null}
- ) : (
-
-
-
-
-
-
-
-
-
-
)}
);
diff --git a/src/stories/screens/SalesReceipt/index.js b/src/stories/screens/SalesReceipt/index.js
index e9d56c8..034d973 100644
--- a/src/stories/screens/SalesReceipt/index.js
+++ b/src/stories/screens/SalesReceipt/index.js
@@ -29,8 +29,14 @@ class SalesReceipt extends React.Component {
onCancelOrder,
isViewingOrder,
isCurrencyDisabled,
+ enableOverallTax,
+ roundOff,
} = this.props;
- const totalPayment = receipt ? receipt.netTotal.toFixed(2) : "0.00";
+ const totalPayment = receipt
+ ? roundOff
+ ? receipt.netTotalRoundOff
+ : receipt.netTotal.toFixed(2)
+ : "0.00";
return (
@@ -43,12 +49,25 @@ class SalesReceipt extends React.Component {
/>
diff --git a/src/stories/screens/Settings/index.js b/src/stories/screens/Settings/index.js
index dd5c7ac..0409847 100644
--- a/src/stories/screens/Settings/index.js
+++ b/src/stories/screens/Settings/index.js
@@ -19,6 +19,7 @@ import Icon from "react-native-vector-icons/FontAwesome";
import { currentLanguage } from "../../../translations/CurrentLanguage";
import CompanySettings from "@components/CompanyComponent";
+import MoreSettings from "@components/MoreSettingsComponent";
import PrinterSettings from "@components/PrinterSettingsComponent";
import BluetoothScanner from "../../components/BluetoothScannerComponent";
import AddAttendant from "../../components/AddAttendantComponent";
@@ -163,6 +164,13 @@ class Settings extends React.Component {
editStatus,
toggleCurrencyDisabled,
isCurrencyDisabled,
+ changeNoReceipts,
+ toggleItemSize,
+ toggleEnableOverallTax,
+ enableOverallTax,
+ toggleMultipleMop,
+ toggleAllowRoundOff,
+ toggleHideMenuBar,
} = this.props;
if (this.props.returnValue === strings.Bluetooth) {
@@ -199,6 +207,7 @@ class Settings extends React.Component {
{
changeEditStatus(false);
onCompanySave();
@@ -282,7 +293,18 @@ class Settings extends React.Component {
/>
);
}
-
+ if (this.props.returnValue === "More...") {
+ return (
+ toggleItemSize(size)}
+ toggleMultipleMop={size => toggleMultipleMop(size)}
+ toggleAllowRoundOff={toggleAllowRoundOff}
+ toggleHideMenuBar={toggleHideMenuBar}
+ />
+ );
+ }
return null;
};
@@ -291,7 +313,9 @@ class Settings extends React.Component {
{ name: strings.Bluetooth },
{ name: strings.Company },
{ name: strings.Sync },
+ { name: "More..." },
];
+
if (this.props.attendant && this.props.attendant.role === "Owner") {
menuItems = [
{ name: strings.Bluetooth },
@@ -299,6 +323,7 @@ class Settings extends React.Component {
{ name: strings.Attendant },
{ name: strings.Sync },
{ name: strings.Queueing },
+ { name: "More..." },
];
}
strings.setLanguage(currentLanguage().companyLanguage);
diff --git a/src/translations/en.js b/src/translations/en.js
index e594657..5d45a7c 100644
--- a/src/translations/en.js
+++ b/src/translations/en.js
@@ -209,8 +209,10 @@ export default {
GenerateZReading: "Generate Z Reading",
NoZReadingGenerated: "No Z Reading Generated",
ZReading: "Z Reading",
+ ZReadin: "Z Reading",
Opened: "Opened",
By: "by",
+ by: "by",
TotalNetSales: "Total Net Sales",
Transactions: "Transactions",
OpeningAmount: "Opening Amount",
diff --git a/src/utils.js b/src/utils.js
index bdc3d28..24edf40 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -35,6 +35,7 @@ export const createReceiptLine = (item, category) => {
category: category,
item_name: item.description,
price: parseFloat(item.price),
+ tax: parseFloat(item.tax),
qty: 1,
});
};
diff --git a/yarn.lock b/yarn.lock
index 6af05e6..ba3554d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7261,6 +7261,11 @@ react-native-iphone-x-helper@^1.0.1:
resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.0.2.tgz#7dbca530930f7c1ce8633cc8fd13ba94102992e1"
integrity sha512-5FYNC4kTi/YK86l+r8GQ0xgsSL2tleCQ5Yppu1+ARbnm2qGRmDoJTGSNsWBAWa8FP1ORyhMjxi18IlvSRKaI2g==
+react-native-key-event@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/react-native-key-event/-/react-native-key-event-1.0.0.tgz#021a9a465e383db8855e3fa53cb4c4a46377bfb2"
+ integrity sha512-bb57EC7q9Y+YUS29Z461neSZlMYKq92x1J1zOd+TdE9Sos3Iqz+c1AwCpng1ob4nR2FUwqI+QAQ3j57rHF5dRQ==
+
react-native-keyboard-aware-scroll-view@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/react-native-keyboard-aware-scroll-view/-/react-native-keyboard-aware-scroll-view-0.5.0.tgz#57ab933089375bf62f4324797e8be949ad97849d"
@@ -7293,6 +7298,11 @@ react-native-modal@^6.0.0:
prop-types "^15.6.1"
react-native-animatable "^1.2.4"
+react-native-nfc-manager@^1.2.2:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/react-native-nfc-manager/-/react-native-nfc-manager-1.2.6.tgz#5399166960be750a40610f645b5b6bc62d94f826"
+ integrity sha512-qGJ7D73RXqkYZ0EJlP5/8f2P9AhqrsMTlS+kiysQH5hJ6WWW25LmB8e1Vrp08DenaCtd5CO+mqj+43zm99C62w==
+
react-native-orientation@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/react-native-orientation/-/react-native-orientation-3.1.3.tgz#d45803841fe94b6cce9acbe904fd5ca191a3711e"