最初の質問は開発ツールです。 サーバーの新しいNodeJSタイプを使用して、クライアントにWebインターフェースを提供することができました。これは最も単純ですが、最も抑制的なオプションです(同様のソリューションにはi3が必要です)。 サーバー部分、アプリケーションごとに別々に登録できます(windows / android / ios)。 または、NodeJSサーバー、およびすべてのクライアントに同じコードのC#(正確にはxamarin)。 または、最新のRadスタジオを使用して、すべてを単一のコードベースで記述します。 同じことを説明するさまざまなコードが潜在的な問題であり、プロジェクトだけで作業することを理解したため、最後のオプションを選択しました。
2番目の質問はアーキテクチャです。 コンポーネントをフォームにすばやく配置したり、ペンを使用したり、LiveBindingを使用してすべてを結び付けて、すぐに結果を得ることができます。 しかし、一部のアルゴリズムの小さな変更には、すべてのプログラムの再構築と更新が必要であり、これは非常に時間のかかるテストであるため、他の場所で中断することはありません。 したがって、xmlを使用してすべてのテーブルとインターフェイスを記述し、すべてのロジックをスクリプトに入れることにしました。
これを行うには、独自のフォームエディターを作成し、RTTIを使用してすべてのプロパティとサブプロパティを使用しました。

スクリーンショットは、要素がOrdersテーブルに接続されていることを示していますが、そのコンテンツは表示されていませんが、顧客へのリンクであるFirstName列(顧客名)を表示しています。 また、押されるとatApplyChangesハンドラーが呼び出され、フォーム上のすべての変更が適用されて閉じられます。 1行のコードなし! 当然、Ordersテーブルで何かが変更されると、変更の正確性をチェックするスクリプトが呼び出されます。 次のようなもの:
ちょっとしたスクリプト
CurOrderState := GetNewValueF('Orders','OrderState');
LastOrderState := GetOldValueF('Orders','OrderState');
IsCashbackOnCurier := GetNewValue('Orders','CashbackOnDeliverer') = 'True';
PayType := GetNewValueF('Orders','PayType');
OldPayType := GetOldValueF('Orders','PayType');
OrderTurn := GetNewValueF('Orders','Turn');
CurTurn := GetConstantValue('CurrentTurn');
OrderNo := GetNewValue('Orders','OrderNo');
OrderPrice := GetNewValueF('Orders','Price');
PaySum := GetNewValueF('Orders','PaySum');
LastPaySum := GetOldValueF('Orders','PaySum');
CurTurn := GetConstantValue('CurrentTurn');
CurCashbox := GetConstantValue('CurrentCashbox');
if (OrderTurn > 0) and (OrderTurn <> CurTurn) then
begin
ShowMessage(' . №'+IntToStr(OrderNo));
exit;
end;
if (LastOrderState = 9) then
begin
ShowMessage(' ');
exit;
end;
if (LastOrderState = 8) then
begin
ShowMessage(' ');
exit;
end;
if (LastOrderState <> 8) and (CurOrderState = 8) then
begin
TransactionCanAccept;
exit;
end;
if (CurOrderState > 2) and (CurTurn < 1) then
begin
ShowMessage(' . ');
exit;
end;
if (CurOrderState > 4) and (CurCashbox < 1) and (CurOrderState <> 8) then
begin
ShowMessage(' . ');
exit;
end;
// , .
if IsCashbackOnCurier then
begin
if PaySum <> LastPaySum then
begin
ShowMessage(' ');
exit;
end;
Price := GetNewValueF('Orders','Price');
LastPrice := GetOldValueF('Orders','Price');
if Price <> LastPrice then
begin
ShowMessage(' ');
exit;
end;
end;
//
if (CurOrderState >= 6) and (CurOrderState < 8) and (PayType = 1) and (not IsCashbackOnCurier) then
begin
if (PaySum - OrderPrice) > 0 then
begin
ss := ' №'+IntToStr(OrderNo);
CreateCashboxDoc(ss,1,OrderPrice - PaySum);
IsCashbackOnCurier := True;
SetValue('Orders','CashbackOnDeliverer',True);
end;
end;
//
if (CurOrderState < 6) and IsCashbackOnCurier then
begin
if (PaySum - OrderPrice) > 0 then
begin
CreateCashboxDoc(' №'+IntToStr(OrderNo),1,PaySum - OrderPrice);
IsCashbackOnCurier := False;
SetValue('Orders','CashbackOnDeliverer',False);
end;
end;
//
if (CurOrderState >= 8) and IsCashbackOnCurier then
begin
if (PaySum - OrderPrice) > 0 then
begin
ss := ' №'+IntToStr(OrderNo);
CreateCashboxDoc(ss,1,PaySum - OrderPrice);
IsCashbackOnCurier := False;
SetValue('Orders','CashbackOnDeliverer',False);
end;
end;
//
if (CurOrderState = 9) and (LastOrderState <> 9) and (PayType = 1) then
begin
ss := ' №'+IntToStr(OrderNo);
CreateCashboxDoc(ss,2,OrderPrice);
end;
//
if (LastOrderState < 3) and (CurOrderState >= 3) then
begin
if CurTurn <= 0 then
begin
ShowMessage(' . .');
exit;
end;
SetValue('Orders','Turn',CurTurn);
CurFilial := GetConstantValue('FilialID');
SetValue('Orders','Filial',CurFilial);
end;
if (CurOrderState <= 2) and (LastOrderState > 2) then
begin
SetValue('Orders','Turn',0);
end;
TransactionCanAccept;
, , / .. -, . .
, – . select . .. + +select+gzip — , - . , , . , , . update/insert, .
. select 10 , , , , ( )? :
fids := CComponentBaseLink.ClassGetPrintValue('Orders_Delivery_Details','Order|Orders->CustomerAddress|Customer_address->FiasHouse|Fias_Houses->ID',orid);
if not StrToInteger(fids,fid) then
Continue;
las := g_Base.GetTblValueByID('Fias_Houses','PointLatitude',fid);
los := g_Base.GetTblValueByID('Fias_Houses','PointLongitude',fid);
.. 3 , . , . api. “ ”, , . api 1.1 , .
, - () -. - ( ) . , pdf. , ( , , raw socket), pdf , . . -, , , -, . , . , .
.

. . . . , , . , -, ; , , 2 , .
, , , . … . : , - -, ( , , « »)… “ ”, “ , ” .. . . , , , ERP . - , ( ) , .. , – . ERP , . :)
P.S. , , - RAD Studio. : , . TWebBrowser, OS. TGrid . . , apk ~ 100Mb. , , , . , , FireMonkey , vcl. Rad studio – . .