unit View.SelectCustomer;

interface

uses
  System.SysUtils, System.Generics.Collections, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
  WEBLib.Forms, WEBLib.Dialogs, WEBLib.Menus, WEBLib.ExtCtrls, WEBLib.StdCtrls,
  WEBLib.JSON, Auth.Service, XData.Web.Client, WebLib.Storage,
  ConnectionModule, App.Types, Vcl.StdCtrls, Vcl.Controls, WEBLib.DBCtrls,
  Data.DB, XData.Web.JsonDataset, XData.Web.Dataset, WEBLib.DB, VCL.TMSFNCTypes, VCL.TMSFNCUtils,
  VCL.TMSFNCGraphics, VCL.TMSFNCGraphicsTypes, VCL.TMSFNCGridCell,
  VCL.TMSFNCGridOptions, VCL.TMSFNCCustomControl, VCL.TMSFNCCustomScrollControl,
  VCL.TMSFNCGridData, VCL.TMSFNCCustomGrid, VCL.TMSFNCGrid;

type
  TFSelectCustomer = class(TWebForm)
    WebLabel1: TWebLabel;
    WebLabel2: TWebLabel;
    edtSearch: TWebEdit;
    edtName: TWebEdit;
    TMSFNCGrid1: TTMSFNCGrid;
    btnCancel: TWebButton;
    btnConfirm: TWebButton;
    XDataWebClient1: TXDataWebClient;
    xdwdsCustomers: TXDataWebDataSet;
    wdsCustomers: TWebDataSource;
    xdwdsCustomersBillAddr: TStringField;
    xdwdsCustomersCompanyName: TStringField;
    xdwdsCustomersId: TStringField;
    xdwdsCustomersPrimaryPhone: TStringField;
    xdwdsCustomersShipAddr: TStringField;
    xdwdsCustomersShipAddrLine1: TStringField;
    xdwdsCustomersShipAddrCity: TStringField;
    xdwdsCustomersShipAddrState: TStringField;
    xdwdsCustomersShipAddrZip: TStringField;
    xdwdsCustomersBillAddrLine1: TStringField;
    xdwdsCustomersBillAddrCity: TStringField;
    xdwdsCustomersBillAddrState: TStringField;
    xdwdsCustomersBillAddrZip: TStringField;
    WebLabel3: TWebLabel;
    edtID: TWebEdit;
    xdwdsCustomersInKGOrders: TBooleanField;
    procedure WebFormCreate(Sender: TObject);
    procedure WebFormShow(Sender: TObject);
    procedure TMSFNCGrid1CellDblClick(Sender: TObject; ACol, ARow: Integer);
    procedure btnConfirmClick(Sender: TObject);
    procedure TMSFNCGrid1CellClick(Sender: TObject; ACol, ARow: Integer);
    procedure edtSearchChange(Sender: TObject);
    procedure btnCancelClick(Sender: TObject);
  private
    { Private declarations }
    [Async] procedure GetCustomers();
    [Async] procedure SendCustomerToServer();
    procedure PopulateGridManually();
    procedure ApplyFilter();
    var
      customerID: string;
      msg: string;
  public
    { Public declarations }
  end;

var
  FSelectCustomer: TFSelectCustomer;

implementation

{$R *.dfm}

uses View.Main, Utils;

procedure TFSelectCustomer.WebFormCreate(Sender: TObject);
begin
  if not DMConnection.ApiConnection.Connected then
   begin
    DMConnection.ApiConnection.OpenAsync;
    console.log('report requirements connection open')
   end;
end;

procedure TFSelectCustomer.WebFormShow(Sender: TObject);
begin
  getCustomers();
end;

procedure TFSelectCustomer.btnCancelClick(Sender: TObject);
begin
  Close();
end;

procedure TFSelectCustomer.btnConfirmClick(Sender: TObject);
begin
  if edtID.Text = '' then
    ShowToast('Please Select a Customer', 'danger')
  else
  begin
    xdwdsCustomers.Locate('Id', edtID.Text, []);
    SendCustomerToServer();
  end;
end;

procedure TFSelectCustomer.edtSearchChange(Sender: TObject);
begin
  ApplyFilter();
end;

procedure TFSelectCustomer.getCustomers();
// retrieves customer list from server
var
  xdcResponse: TXDataClientResponse;
  customerList: TJSObject;
  i: integer;
begin
  try
    Utils.ShowSpinner('spinner');
    // Fetch data from XData service
    xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.getQBCustomers', []));
    customerList := TJSObject(xdcResponse.Result);

    // Load data into TXDataWebDataset
    xdwdsCustomers.Close;
    xdwdsCustomers.SetJsonData(customerList);
    xdwdsCustomers.Open;

    // Manually populate the grid
    PopulateGridManually;
  except
    on E: EXDataClientRequestException do
      Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
  end;
end;


procedure TFSelectCustomer.PopulateGridManually;
// populates the grid with customers manually.
var
  RowIndex: Integer;
begin
  TMSFNCGrid1.BeginUpdate;
  try
    TMSFNCGrid1.Clear; // Clear any existing data

    // Set up column headers
    TMSFNCGrid1.ColumnCount := 4;
    TMSFNCGrid1.RowCount := 1;
    TMSFNCGrid1.Cells[0, 0] := 'Quickbooks ID';
    TMSFNCGrid1.Cells[1, 0] := 'Customer Name';
    TMSFNCGrid1.Cells[2, 0] := 'Address';
    TMSFNCGrid1.Cells[3, 0] := 'In KGOrders';

    // Populate the grid with data from the dataset
    xdwdsCustomers.First;
    RowIndex := 1;

    while not xdwdsCustomers.EOF do
    begin
      TMSFNCGrid1.RowCount := RowIndex + 1;
      TMSFNCGrid1.Cells[0, RowIndex] := xdwdsCustomers.FieldByName('Id').AsString;
      TMSFNCGrid1.Cells[1, RowIndex] := xdwdsCustomers.FieldByName('CompanyName').AsString;
      TMSFNCGrid1.Cells[2, RowIndex] := xdwdsCustomers.FieldByName('BillAddr').AsString;
      TMSFNCGrid1.Cells[3, RowIndex] := xdwdsCustomers.FieldByName('In KGOrders').AsString;
      Inc(RowIndex);
      xdwdsCustomers.Next;
    end;

  finally
    TMSFNCGrid1.EndUpdate;
  end;
  Utils.HideSpinner('spinner');
end;

procedure TFSelectCustomer.TMSFNCGrid1CellClick(Sender: TObject; ACol,
  ARow: Integer);
begin
  edtID.Text := TMSFNCGrid1.Cells[0, ARow];
  edtName.Text := TMSFNCGrid1.Cells[1, ARow];
end;

procedure TFSelectCustomer.TMSFNCGrid1CellDblClick(Sender: TObject; ACol,
  ARow: Integer);
begin
  edtID.Text := TMSFNCGrid1.Cells[2, ARow];
  xdwdsCustomers.Locate('Id', TMSFNCGrid1.Cells[0, ARow], [] );
end;

procedure TFSelectCustomer.SendCustomerToServer;
var
  CustomerJSON: TJSONObject;
  Response: TXDataClientResponse;
  notification: TJSObject;
begin
  CustomerJSON := TJSONObject.Create;
  CustomerJSON.AddPair('NAME', xdwdsCustomers.FieldByName('CompanyName').AsString);
  CustomerJSON.AddPair('QB_LIST_ID', xdwdsCustomers.FieldByName('Id').AsString);
  CustomerJSON.AddPair('PHONE', xdwdsCustomers.FieldByName('PrimaryPhone').AsString);
  CustomerJSON.AddPair('BILL_ADDRESS', xdwdsCustomers.FieldByName('BillAddrLine1').AsString);
  CustomerJSON.AddPair('BILL_CITY', xdwdsCustomers.FieldByName('BillAddrCity').AsString);
  CustomerJSON.AddPair('BILL_STATE', xdwdsCustomers.FieldByName('BillAddrState').AsString);
  CustomerJSON.AddPair('BILL_ZIP', xdwdsCustomers.FieldByName('BillAddrZip').AsString);
  CustomerJSON.AddPair('BILL_ADDRESS_BLOCK', xdwdsCustomers.FieldByName('BillAddr').AsString);

  CustomerJSON.AddPair('address', xdwdsCustomers.FieldByName('ShipAddrLine1').AsString);
  CustomerJSON.AddPair('city', xdwdsCustomers.FieldByName('ShipAddrCity').AsString);
  CustomerJSON.AddPair('state', xdwdsCustomers.FieldByName('ShipAddrState').AsString);
  CustomerJSON.AddPair('zip', xdwdsCustomers.FieldByName('ShipAddrZip').AsString);
  CustomerJSON.AddPair('ship_block', xdwdsCustomers.FieldByName('ShipAddr').AsString);
  CustomerJSON.AddPair('name', xdwdsCustomers.FieldByName('CompanyName').AsString);
  CustomerJSON.AddPair('mode', 'ADD');

  Utils.ShowSpinner('spinner');

  Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.ImportQBCustomer',
              [customerJSON.ToString]));

  notification := TJSObject(Response.Result);

  customerID := string(notification['CustomerID']);
  msg := string(notification['status']);
  Utils.HideSpinner('spinner');
  FViewMain.ViewAddCustomer(customerID, msg);
  Close();

end;

procedure TFSelectCustomer.ApplyFilter;
// filters the grid based on search textbox contents.
var
  fd: TTMSFNCGridFilterData;
  i: Integer;
  SearchText: string;
begin
  SearchText := Trim(edtSearch.Text);

  TMSFNCGrid1.RemoveFilter;
  TMSFNCGrid1.Filter.Clear;

  // match on first 3 columns
  for i := 0 to 2 do
  begin
    fd := TMSFNCGrid1.Filter.Add;
    fd.Column := i;
    fd.Condition := '*' + SearchText + '*'; // Match text anywhere in the cell
    fd.CaseSensitive := False; // Make the filter case-insensitive

    // Use foOR for "match any column" logic
    if i > 0 then
      fd.Operation := foOR
    else
      fd.Operation := foNONE; // First filter has no logical operation
  end;

  // Apply the filters to the grid
  TMSFNCGrid1.ApplyFilter;
end;

end.