Skip to content

Commit 234aa93

Browse files
committed
Merge branch 'develop'
2 parents 9137162 + 2388f21 commit 234aa93

File tree

190 files changed

+5816
-5057
lines changed

Some content is hidden

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

190 files changed

+5816
-5057
lines changed

.github/workflows/client-bundle-size-diff.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
NODE_AUTH_TOKEN: ${{secrets.TOKEN_REPO}}
2222

2323
- name: Build
24-
run: cd ./client && yarn build-dev
24+
run: cd ./client && yarn build-stats
2525

2626
- name: Upload base stats.json
2727
uses: actions/upload-artifact@v2
@@ -43,7 +43,7 @@ jobs:
4343
NODE_AUTH_TOKEN: ${{secrets.TOKEN_REPO}}
4444

4545
- name: Build
46-
run: cd ./client && yarn build-dev
46+
run: cd ./client && yarn build-stats
4747

4848
- name: Upload base stats.json
4949
uses: actions/upload-artifact@v2

README.md

+14-1
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,25 @@ Used in over 30 countries and for over 20 years and now becoming open source.
66
The code is separated into two main areas, the client and server:
77

88
### Client
9+
910
Built on [React](https://reactjs.org/) - a responsive, multi-lingual, web based client, also packaged as both a desktop and android app.
1011

1112
For more information, [read the client developer docs](client/README.md)
1213

13-
1414
### Server
15+
1516
Built to be fast and reliable using [Rust](https://www.rust-lang.org/) and supporting either [PostgreSQL](https://www.postgresql.org/) or [SQLite](https://www.sqlite.org/index.html) databases.
1617

1718
For more information, [read the server developer docs](server/README.md)
19+
20+
### Architecture
21+
22+
The client application is a web app, which is compiled and then hosted by the server. This can also be hosted externally by any web server, though this is no longer the recommended approach. The server connects to the database and provides a graphQL API which is consumed by the client app.
23+
24+
Users browse to the client app on the configured server port from a web browser, or the various wrappers which provide platform specific capabilities. This web app then connects to the server using graphQL in order to fetch data, and to the web server for app resources.
25+
26+
In diagrammatic form this looks like the image below:
27+
28+
![omSupply Architecture drawio](./architecture.drawio.svg)
29+
30+
There are also several ancilliary applications as noted, which are available to be run (cli applications) or hosted (storybook) separately.

architecture.drawio.svg

+425
Loading

build/windows/omsupply_server.suf

+17-16
Original file line numberDiff line numberDiff line change
@@ -956,8 +956,8 @@ Screen.Back();
956956
<Script>-- These actions are performed when the Next button is clicked.
957957
local sNextScreenName = "Select Install Folder";
958958

959-
tRbSqliteProps = DlgRadioButton.GetProperties(CTRL_RADIO_BUTTON_01);
960-
if not tRbSqliteProps.Checked then
959+
tRbSqliteProps = DlgRadioButton.GetProperties(CTRL_RADIO_BUTTON_02); -- If postgres is selected as db
960+
if tRbSqliteProps.Checked then
961961
SessionVar.Set("%omsupply_selected_db%", "postgres");
962962
sNextScreenName = "Postgres Configuration";
963963
else
@@ -2842,7 +2842,7 @@ end
28422842
<Visible>1</Visible>
28432843
<Enabled>1</Enabled>
28442844
<TabOrder>5</TabOrder>
2845-
<Checked>1</Checked>
2845+
<Checked>0</Checked>
28462846
<Variable>cbStartOmSupply</Variable>
28472847
</Control>
28482848
<Control>
@@ -4056,25 +4056,14 @@ g_HandleSystemReboot();
40564056
<Args/>
40574057
<Script>-- Set window title
40584058
local sWindowTitle = "omSupply Server Setup";
4059-
4060-
hasOmsupplyInstalled = false;
4061-
omSupplyServerDatabase = SessionVar.Get("%omsupply_selected_db%");
4062-
4063-
if (omSupplyServerDatabase == "sqlite") then
4064-
omSupplyServerPath = SessionVar.Expand("%AppFolder%\\omSupply-sqlite.exe");
4065-
else
4066-
omSupplyServerPath = SessionVar.Expand("%AppFolder%\\omSupply-postgres.exe");
4067-
end
4059+
local omSupplyServerPath = "";
40684060

40694061
-- Check if the omSupply Server has been already installed on this machine
40704062
if Registry.DoesKeyExist(HKEY_LOCAL_MACHINE, "Software\\omSupply Server") then
40714063
omSupplyServerPath = Registry.GetValue(HKEY_LOCAL_MACHINE, "Software\\omSupply Server", "Path", true);
4072-
omSupplyServerDatabase = Registry.GetValue(HKEY_LOCAL_MACHINE, "Software\\omSupply Server", "Database", true);
4073-
if File.DoesExist(omSupplyServerPath) then
4074-
hasOmsupplyInstalled = true;
4075-
end
40764064
end
40774065

4066+
hasOmsupplyInstalled = File.DoesExist(omSupplyServerPath);
40784067
if hasOmsupplyInstalled then
40794068
sWindowTitle = "omSupply Server Upgrader Setup";
40804069
end
@@ -4167,6 +4156,18 @@ end
41674156
<Name>On Post Install</Name>
41684157
<Args/>
41694158
<Script>local sFileToBeDeletePath = "";
4159+
local omSupplyServerPath = SessionVar.Expand("%AppFolder%\\omSupply-sqlite.exe");
4160+
local omSupplyServerDatabase = SessionVar.Get("%omsupply_selected_db%");
4161+
4162+
-- Get current database name from registry (if already installed)
4163+
if hasOmsupplyInstalled then
4164+
omSupplyServerDatabase = Registry.GetValue(HKEY_LOCAL_MACHINE, "Software\\omSupply Server", "Database", true);
4165+
end
4166+
4167+
if (omSupplyServerDatabase == "postgres") then
4168+
omSupplyServerPath = SessionVar.Expand("%AppFolder%\\omSupply-postgres.exe");
4169+
end
4170+
41704171
if not hasOmsupplyInstalled then
41714172
local config = "server:\r\n"
41724173
config = config .. " host: 192.168.178.68\r\n";

client/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"start-remote": "lerna run --scope @openmsupply-client/* --parallel start-remote",
88
"start": "yarn start-remote",
99
"build": "lerna run --scope @openmsupply-client/* build",
10-
"build-dev": "lerna run --scope @openmsupply-client/* build-dev",
10+
"build-stats": "lerna run --scope @openmsupply-client/* build-stats",
1111
"serve": "lerna run --scope @openmsupply-client/* --parallel serve",
1212
"clean": "lerna run --scope @openmsupply-client/* --parallel clean",
1313
"compile": "lerna run --scope @openmsupply-client/* --parallel tsc --since HEAD",

client/packages/common/src/hooks/useUrlQuery/useUrlQueryParams.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ export const useUrlQueryParams = ({
6767
filterBy:
6868
filterKey && urlQuery[filterKey]
6969
? {
70-
[filterKey]: { [filterCondition]: urlQuery[filterKey] ?? '' },
70+
[filterKey]: {
71+
[filterCondition]: String(urlQuery[filterKey]) ?? '',
72+
},
7173
}
7274
: {},
7375
};

client/packages/common/src/intl/context/IntlContext.tsx

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import Backend from 'i18next-chained-backend';
44
import LocalStorageBackend from 'i18next-localstorage-backend';
55
import HttpApi from 'i18next-http-backend';
66
import { I18nextProvider, initReactI18next } from 'react-i18next';
7+
import LanguageDetector from 'i18next-browser-languagedetector';
8+
import { browserLanguageDetector } from './browserLanguageDetector';
79
import { PropsWithChildrenOnly } from '@common/types';
810
import { EnvUtils, Platform } from '@common/utils';
911

@@ -12,6 +14,9 @@ export const IntlProvider: FC<PropsWithChildrenOnly> = ({ children }) => {
1214
React.useEffect(() => {
1315
if (i18next.isInitialized) return;
1416

17+
const languageDetector = new LanguageDetector();
18+
languageDetector.addDetector(browserLanguageDetector);
19+
1520
const minuteInMilliseconds = 60 * 1000;
1621
const isDevelopment = process.env['NODE_ENV'] === 'development';
1722
const expirationTime = isDevelopment
@@ -29,6 +34,7 @@ export const IntlProvider: FC<PropsWithChildrenOnly> = ({ children }) => {
2934
i18next
3035
.use(initReactI18next) // passes i18n down to react-i18next
3136
.use(Backend)
37+
.use(languageDetector)
3238
.init({
3339
backend: {
3440
backends: [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { CustomDetector } from 'i18next-browser-languagedetector';
2+
3+
export const browserLanguageDetector: CustomDetector = {
4+
name: 'omsBrowserLanguageDetector',
5+
// the language is now supplied by the user profile
6+
// and set on login, so the below code is not actually needed
7+
// Implementing the language detector allows the language
8+
// to be cached in the browser and retained on page refresh
9+
lookup: () => {
10+
const found: string[] = [];
11+
const add = (languageOrLocale?: string) => {
12+
if (!languageOrLocale) return;
13+
const parsed = /(^[a-z]{2})(-(.*))?/.exec(languageOrLocale);
14+
if (parsed) {
15+
if (parsed.length > 1 && !!parsed[1]) found.push(parsed[1]);
16+
} else {
17+
found.push(languageOrLocale);
18+
}
19+
};
20+
if (typeof navigator !== 'undefined') {
21+
if (navigator.languages) {
22+
// chrome only; not an array, so can't use .push.apply instead of iterating
23+
for (let i = 0; i < navigator.languages.length; i++) {
24+
const locale = navigator.languages[i];
25+
add(locale);
26+
}
27+
}
28+
if ((navigator as any).userLanguage) {
29+
add((navigator as any).userLanguage);
30+
}
31+
if (navigator.language) {
32+
add(navigator.language);
33+
}
34+
}
35+
return found.length > 0 ? found : undefined;
36+
},
37+
};

client/packages/common/src/intl/currency/currency.ts

+10-9
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ const currencyOptions = {
7272
symbol: '$',
7373
separator: ',',
7474
decimal: '.',
75-
precision: 10,
75+
precision: 2,
7676
pattern: '!#',
7777
negativePattern: '-!#',
7878
format,
@@ -81,7 +81,7 @@ const currencyOptions = {
8181
symbol: 'XOF',
8282
separator: '.',
8383
decimal: ',',
84-
precision: 10,
84+
precision: 2,
8585
pattern: '# !',
8686
negativePattern: '-# !',
8787
format,
@@ -90,25 +90,26 @@ const currencyOptions = {
9090
symbol: 'ر.ق.',
9191
separator: ',',
9292
decimal: '.',
93-
precision: 10,
93+
precision: 2,
9494
pattern: '!#',
9595
negativePattern: '-!#',
9696
format,
9797
},
9898
};
9999

100-
export const useCurrency = () => {
100+
export const useCurrency = (dp?: number) => {
101101
const language = IntlUtils.useCurrentLanguage();
102102
const options = currencyOptions[language];
103+
const precision = dp ?? options.precision;
103104
return {
104-
c: (value: currency.Any) => currency(value, options),
105+
c: (value: currency.Any) => currency(value, { ...options, precision }),
105106
options,
106-
language,
107-
};
107+
language
108+
}
108109
};
109110

110-
export const useFormatCurrency = () => {
111-
const { c } = useCurrency();
111+
export const useFormatCurrency = (dp?: number) => {
112+
const { c } = useCurrency(dp);
112113
return (value: currency.Any) => c(value).format();
113114
};
114115

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

+10
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"description.pack-quantity": "Total quantity in number of packs",
3131
"description.remaining-to-supply": "The quantity remaining to be supplied, which is the Supply quantity less the quantity of this item on any linked Outbound Shipment",
3232
"description.requested-quantity": "Quantity requested by customer",
33+
"description.soh": "Stock on Hand",
3334
"description.stock-on-hand": "Stock on Hand (Est. remaining)",
3435
"description.supply-quantity": "The quantity that will be supplied by this store",
3536
"description.total": "Total value",
@@ -102,6 +103,7 @@
102103
"label.edited-by": "Edited by",
103104
"label.entered": "Created",
104105
"label.entered-by": "Entered by",
106+
"label.event": "Event",
105107
"label.expand": "Expand",
106108
"label.expand-all": "Expand all",
107109
"label.expiring-soon": "Expiring Soon",
@@ -154,6 +156,7 @@
154156
"label.settings-username": "Site name",
155157
"label.shipped": "Shipped",
156158
"label.snapshot-num-of-packs": "Snapshot # of Packs",
159+
"label.soh": "SOH",
157160
"label.status": "Status",
158161
"label.stock-on-hand": "SoH (Est. remaining)",
159162
"label.suggested": "Suggested",
@@ -188,6 +191,13 @@
188191
"log.requisition-deleted": "Requisition deleted",
189192
"log.requisition-status-sent": "Requisition sent",
190193
"log.requisition-status-finalised": "Requisition finalised",
194+
"log.stock-batch-change": "Batch changed",
195+
"log.stock-cost-price-change": "Cost price changed",
196+
"log.stock-expiry-date-change": "Expiry date changed",
197+
"log.stock-location-change": "Location changed",
198+
"log.stock-off-hold": "Stock off hold",
199+
"log.stock-on-hold": "Stock on hold",
200+
"log.stock-sell-price-change": "Sell price changed",
191201
"messages.ago": "{{time}} ago",
192202
"messages.cant-delete-generic": "You cannot delete one or more of the selected items",
193203
"messages.confirm-cancel-generic": "You will lose any changes you have made to this form",

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

+5-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
"error.stocktake-not-found": "Stocktake not found",
1010
"label.add-batch": "Add batch",
1111
"label.add-new-line": "Add a new line",
12+
"label.cost-price": "Cost price",
13+
"label.sell-price": "Sell price",
1214
"label.counted-num-of-packs": "Counted # of Packs",
1315
"label.create-location": "Create Location",
1416
"label.edit-location": "Edit Location",
@@ -26,7 +28,6 @@
2628
"messages.cant-delete-stocktakes": "Can only delete stocktakes with a status of 'New'",
2729
"messages.select-rows-to-delete": "Select rows to delete",
2830
"messages.click-to-return": "Unable to find a stocktake with that ID. Click OK to return to the stocktake list",
29-
"messages.click-to-view-item": "Click to view the item details for '{{itemName}}'",
3031
"messages.confirm-delete-stocktakes_one": "This will permanently remove 1 stocktake",
3132
"messages.confirm-delete-stocktakes_other": "This will permanently remove {{count}} stocktakes",
3233
"messages.confirm-delete-stocktake_lines_one": "This will permanently remove 1 stocktake line",
@@ -41,7 +42,9 @@
4142
"messages.error-deleting-locations_other": "{{count}} locations could not be deleted",
4243
"placeholder.enter-an-item-code-or-name": "Enter item code or name",
4344
"messages.deleted-lines": "Deleted {{count}} lines",
45+
"messages.confirm-save-stock-line": "Do you want to save the changes to this stock line? All changes will be logged and can be reviewed later from this screen.",
4446
"messages.select-rows-to-delete-them": "Select rows to delete them",
4547
"status.new": "New",
46-
"status.finalised": "Finalised"
48+
"status.finalised": "Finalised",
49+
"title.stock-line-details": "Stock Line Details"
4750
}

0 commit comments

Comments
 (0)