独自のERPシステムを作成し、その結果

少し前に、私の寿司屋とピザの配達ネットワークの支店の1つのオーナーである私の友人が私に向き直りました。 彼らの現在のERPは、キッチンと配達人を制御できず、彼が市内に5つのキッチンを持っているので、これは深刻な問題でした。 彼は私が彼のために新しいシステムを書くことを提案しました。 唯一の条件は、彼がフランチャイズにいて、特にボスとの関係を台無しにしたくないので、できるだけ慎重に既存のシステムと統合する必要があったということです。



最初の質問は開発ツールです。 サーバーの新しい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 , . . -, , , -, . , . , .



.



image



. . . . , , . , -, ; , , 2 , .



, , , . … . : , - -, ( , , « »)… “ ”, “ , ” .. . . , , , ERP . - , ( ) , .. , – . ERP , . :)



P.S. , , - RAD Studio. : , . TWebBrowser, OS. TGrid . . , apk ~ 100Mb. , , , . , , FireMonkey , vcl. Rad studio – . .



All Articles