Skip to content

Commit 34a30cf

Browse files
committed
Merge branch 'develop'
2 parents 3ef0f99 + 7f34488 commit 34a30cf

File tree

77 files changed

+1404
-127
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+1404
-127
lines changed

build/windows/demo/local.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ logging:
1212
level: Info
1313
directory: log
1414
filename: remote_server.log
15-
max_file_count: 5
16-
max_file_size: 10
15+
max_file_count: 10
16+
max_file_size: 1
1717

build/windows/omsupply_server.suf

+2-2
Original file line numberDiff line numberDiff line change
@@ -4207,8 +4207,8 @@ else
42074207
config = config .. " level: Warn\r\n";
42084208
config = config .. " directory: log\r\n";
42094209
config = config .. " filename: omsupply.log\r\n";
4210-
config = config .. " max_file_count: 5\r\n";
4211-
config = config .. " max_file_size: 10\r\n";
4210+
config = config .. " max_file_count: 10\r\n";
4211+
config = config .. " max_file_size: 1\r\n";
42124212
TextFile.WriteFromString(SessionVar.Expand("%AppFolder%\\configuration\\local.yaml"), config, false);
42134213

42144214
-- Create omSupply Server keys in registry

build/windows/omsupply_standalone.suf

+2-2
Original file line numberDiff line numberDiff line change
@@ -3362,8 +3362,8 @@ else
33623362
config = config .. " level: Warn\r\n";
33633363
config = config .. " directory: log\r\n";
33643364
config = config .. " filename: omsupply.log\r\n";
3365-
config = config .. " max_file_count: 5\r\n";
3366-
config = config .. " max_file_size: 10\r\n";
3365+
config = config .. " max_file_count: 10\r\n";
3366+
config = config .. " max_file_size: 1\r\n";
33673367
TextFile.WriteFromString(SessionVar.Expand("%AppFolder%\\server\\configuration\\local.yaml"), config, false);
33683368

33693369
-- Create omSupply Server keys in registry

client/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "openmsupply-client",
33
"//": "Version is shared between client and remote server and is located in repo root package.json",
4-
"version": "0.1.0",
4+
"version": "0.0.0",
55
"sideEffects": false,
66
"private": true,
77
"scripts": {

client/packages/android/app/src/main/AndroidManifest.xml

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
<uses-permission android:name="android.permission.INTERNET" />
2424
<uses-permission android:name="android.permission.CAMERA" />
25+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2526

2627
<uses-sdk tools:overrideLibrary="com.google.zxing.client.android" />
2728
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package org.openmsupply.client;
2+
3+
import android.app.Activity;
4+
import android.content.Context;
5+
import android.content.Intent;
6+
import android.net.Uri;
7+
import android.widget.Toast;
8+
9+
import java.io.BufferedWriter;
10+
import java.io.OutputStream;
11+
import java.io.OutputStreamWriter;
12+
13+
public class FileManager {
14+
private static final int SAVE_FILE_REQUEST = 12321;
15+
private Activity activity;
16+
private String content;
17+
18+
public FileManager(Activity activity) {
19+
this.activity = activity;
20+
}
21+
22+
public void Save(String filename, String content) {
23+
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
24+
intent.addCategory(Intent.CATEGORY_OPENABLE);
25+
intent.setType("text/plain");
26+
intent.putExtra(Intent.EXTRA_TITLE, filename);
27+
// This was a neat idea, but only works with small amounts of text!
28+
// With a few hundred KB the file chooser closes immediately on open
29+
// intent.putExtra(Intent.EXTRA_TEXT, content);
30+
this.content = content;
31+
32+
activity.startActivityForResult(intent, SAVE_FILE_REQUEST);
33+
}
34+
35+
public void onActivityResult(int requestCode, int resultCode, Intent data) {
36+
if (requestCode == SAVE_FILE_REQUEST && resultCode == Activity.RESULT_OK && data != null) {
37+
Uri uri = data.getData();
38+
Context context = activity.getApplicationContext();
39+
40+
try {
41+
OutputStream outputStream = context.getContentResolver().openOutputStream(uri);
42+
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
43+
bw.write(content);
44+
bw.flush();
45+
bw.close();
46+
} catch (Exception e) {
47+
Toast.makeText(context, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
48+
}
49+
}
50+
}
51+
}

client/packages/android/app/src/main/java/org/openmsupply/client/MainActivity.java

+16
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
package org.openmsupply.client;
22

3+
import android.content.Intent;
34
import android.os.Bundle;
45
import com.getcapacitor.BridgeActivity;
56

67
public class MainActivity extends BridgeActivity {
78
RemoteServer server = new RemoteServer();
89
DiscoveryConstants discoveryConstants;
10+
private FileManager fileManager;
911

1012
@Override
1113
protected void onCreate(Bundle savedInstanceState) {
1214
registerPlugin(NativeApi.class);
1315
super.onCreate(savedInstanceState);
1416

1517
discoveryConstants = new DiscoveryConstants(getContentResolver());
18+
fileManager = new FileManager(this);
1619

1720
String path = getFilesDir().getAbsolutePath();
1821
String cache = getCacheDir().getAbsolutePath();
@@ -24,4 +27,17 @@ public void onDestroy() {
2427
super.onDestroy();
2528
server.stop();
2629
}
30+
31+
// ActivityResult needs to be overridden in the main, not UI thread
32+
@Override
33+
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
34+
super.onActivityResult(requestCode, resultCode, data);
35+
36+
fileManager.onActivityResult(requestCode, resultCode, data);
37+
}
38+
39+
// Implementing here, so that we can use the FileManager instance
40+
public void SaveFile(String filename, String content) {
41+
fileManager.Save(filename, content);
42+
}
2743
}

client/packages/android/app/src/main/java/org/openmsupply/client/NativeApi.java

+28-4
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@
44

55
import android.net.nsd.NsdManager;
66
import android.net.nsd.NsdServiceInfo;
7+
import android.os.Handler;
8+
import android.os.Looper;
79
import android.util.Log;
810
import android.webkit.WebView;
911

12+
import androidx.annotation.MainThread;
13+
import androidx.annotation.NonNull;
14+
import androidx.appcompat.app.AppCompatActivity;
15+
1016
import com.getcapacitor.Bridge;
1117
import com.getcapacitor.JSArray;
1218
import com.getcapacitor.JSObject;
@@ -28,17 +34,15 @@
2834
import java.util.ArrayDeque;
2935
import java.util.Deque;
3036

31-
import javax.net.ssl.HttpsURLConnection;
3237
import javax.net.ssl.SSLHandshakeException;
33-
import javax.net.ssl.SSLSocketFactory;
3438

3539
@CapacitorPlugin(name = "NativeApi")
3640
public class NativeApi extends Plugin implements NsdManager.DiscoveryListener {
3741
private static final String LOG_FILE_NAME = "remote_server.log";
3842
public static final String OM_SUPPLY = "omSupply";
3943
private static final Integer DEFAULT_PORT = DiscoveryConstants.PORT;
4044
private static final String DEFAULT_URL = "https://localhost:" + DEFAULT_PORT + "/";
41-
private static final String CONFIGURATION_GROUP = "omSupply_preferences";
45+
4246
DiscoveryConstants discoveryConstants;
4347
JSArray discoveredServers;
4448
Deque<NsdServiceInfo> serversToResolve;
@@ -442,7 +446,27 @@ public void readLog(PluginCall call) {
442446
call.resolve(response);
443447
}
444448

445-
/** Helper class to get access to the JS FrontEndHost data */
449+
@PluginMethod()
450+
public void saveFile(@NonNull PluginCall call) {
451+
JSObject data = call.getData();
452+
JSObject response = new JSObject();
453+
454+
String filename = data.getString("filename", LOG_FILE_NAME);
455+
String content = data.getString("content");
456+
457+
if(content == null){
458+
response.put("error", "No content");
459+
response.put("success", false);
460+
}else{
461+
MainActivity mainActivity = (MainActivity) getActivity();
462+
mainActivity.SaveFile(filename, content);
463+
response.put("success", true);
464+
}
465+
466+
call.resolve(response);
467+
}
468+
469+
/** Helper class to get access to the JS FrontEndHost data */
446470
public class FrontEndHost {
447471
JSObject data;
448472

client/packages/common/src/hooks/useDialog/useDialog.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export interface ModalProps {
2929
} & React.RefAttributes<unknown>
3030
>;
3131
okButton?: JSX.Element;
32+
reportSelector?: React.ReactElement;
3233
width?: number;
3334
sx?: SxProps<Theme>;
3435
title: string;
@@ -129,6 +130,7 @@ export const useDialog = (dialogProps?: DialogProps): DialogState => {
129130
height,
130131
nextButton,
131132
okButton,
133+
reportSelector,
132134
width,
133135
title,
134136
contentProps,
@@ -200,6 +202,7 @@ export const useDialog = (dialogProps?: DialogProps): DialogState => {
200202
{cancelButton}
201203
{okButton}
202204
{WrappedNextButton}
205+
{reportSelector}
203206
</DialogActions>
204207
</BasicModal>
205208
);

client/packages/common/src/hooks/useNativeClient/types.ts

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export type ConnectionResult = {
1111
success: boolean;
1212
error?: string;
1313
};
14+
export type FileInfo = {
15+
content: string;
16+
filename?: string;
17+
};
18+
1419
export interface NativeAPI {
1520
// Method used in polling for found servers
1621
discoveredServers: () => Promise<{ servers: FrontEndHost[] }>;
@@ -36,6 +41,9 @@ export interface NativeAPI {
3641
) => void;
3742
setScannerType: (server: ScannerType) => void;
3843
getScannerType: () => Promise<ScannerType>;
44+
saveFile: (
45+
fileInfo: FileInfo
46+
) => Promise<{ success: boolean; error?: string }>;
3947
}
4048

4149
export enum NativeMode {

client/packages/common/src/hooks/useNativeClient/useNativeClient.ts

+13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
ConnectionResult,
1212
DISCOVERED_SERVER_POLL,
1313
DISCOVERY_TIMEOUT,
14+
FileInfo,
1415
FrontEndHost,
1516
NativeAPI,
1617
NativeMode,
@@ -125,6 +126,17 @@ export const useNativeClient = ({
125126
if (result.isSupported) await KeepAwake.keepAwake();
126127
};
127128

129+
const saveFile = async (fileInfo: FileInfo) => {
130+
const result = await nativeAPI?.saveFile(fileInfo);
131+
132+
if (!result) {
133+
console.error('No result from nativeAPI.saveFile');
134+
return;
135+
}
136+
137+
return result;
138+
};
139+
128140
useEffect(() => {
129141
if (!state.isDiscovering) return;
130142

@@ -183,5 +195,6 @@ export const useNativeClient = ({
183195
readLog,
184196
keepAwake,
185197
allowSleep,
198+
saveFile,
186199
};
187200
};

client/packages/common/src/intl/locales/en/common.json

+1
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@
190190
"label.server-log": "Server log",
191191
"label.reference": "Reference",
192192
"label.remaining-to-supply": "Remaining",
193+
"label.repack": "Repack",
193194
"label.requested-quantity": "Requested",
194195
"label.requested-packs": "Requested packs",
195196
"label.approved-packs": "Approved packs",

client/packages/common/src/intl/locales/en/inventory.json

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"button.delete-lines": "Delete selected lines",
3+
"button.repack": "Repack",
34
"button.save-and-confirm-status": "Confirm {{status}}",
45
"error.cant-save": "There was a problem saving.",
56
"error.no-locations": "There are no Locations to display.",
@@ -15,6 +16,8 @@
1516
"error.reduced-below-zero": "Stock line exist in new outbound shipments. The quantity cannot be reduced below zero.",
1617
"error.stocktake-has-stock-reduced-below-zero": "Stock take cannot be finalised because some of the stock has been used in new outbound shipments.",
1718
"error.unable-to-scan": "Unable to scan barcode: {{error}}",
19+
"error.repack-has-stock-reduced-below-zero": "Cannot repack stock line. New number of packs exceeds stock line number of packs.",
20+
"error.repack-cannot-be-fractional": "Cannot repack into a fractional pack",
1821
"label.add-batch": "Add batch",
1922
"label.add-new-line": "Add a new line",
2023
"label.cost-price": "Cost price",
@@ -36,6 +39,11 @@
3639
"label.location": "Location",
3740
"label.master-list": "Master List",
3841
"label.items-with-stock": "Items with Stock",
42+
"label.new": "New",
43+
"label.new-pack-size": "New pack size",
44+
"label.new-num-packs": "New number of packs",
45+
"label.packs-available": "Packs available",
46+
"label.packs-to-repack": "Number of packs to repack",
3947
"message.no-supplier": "Inventory Adjustment",
4048
"messages.locked-description": "This will prevent further changes to the stocktake until it is unlocked.",
4149
"messages.unlocked-description": "This will re-enable changes to the stocktake.",
@@ -64,11 +72,16 @@
6472
"messages.no-items-with-stock": "No items with stock available",
6573
"messages.on-hold-stock-take": "This stocktake is on hold and cannot be edited",
6674
"messages.select-rows-to-delete-them": "Select rows to delete them",
75+
"messages.no-repacks": "This stock line has not been repacked. Click New to create a new repack.",
76+
"messages.no-repack-detail": "Select a line to view the details of a repack or click new to create a new repack",
77+
"messages.all-packs-repacked": "Saved. The previous window has been closed since everything in the stock line has been repacked.",
78+
"messages.repack-log-info": "Repacked from stock line",
6779
"status.new": "New",
6880
"status.finalised": "Finalised",
6981
"stocktake.description-template": "Created by {{username}} on {{date}}",
7082
"stocktake.comment-list-template": "Created using master list '{{list}}'",
7183
"stocktake.comment-location-template": "Created using items in location '{{location}}'",
7284
"stocktake-comment-items-have-stock-template": "Created using items that have stock",
73-
"title.stock-line-details": "Stock Line Details"
85+
"title.stock-line-details": "Stock Line Details",
86+
"title.repack-details": "Repack Details"
7487
}

0 commit comments

Comments
 (0)