From bad2f5f7fcdecbebdc8fa0672132c98b3aeef356 Mon Sep 17 00:00:00 2001 From: Wagner Inaba Date: Sat, 9 Mar 2024 06:03:44 -0300 Subject: [PATCH 1/2] =?UTF-8?q?Sistema=20com=20tela=20de=20login=20e=20cad?= =?UTF-8?q?astro=20de=20ordens=20de=20entrada=20e=20sa=C3=ADda?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/database/desafio_delphi.db | Bin 0 -> 24576 bytes src/database/desafio_delphi.db2 | 0 src/database/desafio_delphi_bk.db | Bin 0 -> 24576 bytes "src/imagens/Diagramas t\303\251cnicos.jpg" | Bin 0 -> 58077 bytes src/imagens/add_button.png | Bin 0 -> 13726 bytes .../DAO/desafio.model.dao.connection.dfm | 11 + .../DAO/desafio.model.dao.connection.pas | 31 + .../desafio.model.implements.connection.pas | 163 +++ .../desafio.model.implements.orders.pas | 215 ++++ .../desafio.model.implements.products.pas | 248 +++++ .../desafio.model.implements.user.pas | 193 ++++ .../desafio.model.interfaces.category.pas | 23 + .../desafio.model.interfaces.connection.pas | 29 + .../desafio.model.interfaces.order_items.pas | 38 + .../desafio.model.interfaces.orders.pas | 44 + .../desafio.model.interfaces.products.pas | 45 + .../desafio.model.interfaces.user.pas | 28 + src/prjDesafioDelphi.dpr | 29 + src/prjDesafioDelphi.dproj | 999 ++++++++++++++++++ src/view/desafio.view.login.dfm | 180 ++++ src/view/desafio.view.login.pas | 66 ++ src/view/desafio.view.main.dfm | 302 ++++++ src/view/desafio.view.main.pas | 291 +++++ src/view/desafio.view.register.product.dfm | 245 +++++ src/view/desafio.view.register.product.pas | 118 +++ src/view/desafio.view.register.user.dfm | 199 ++++ src/view/desafio.view.register.user.pas | 65 ++ 27 files changed, 3562 insertions(+) create mode 100644 src/database/desafio_delphi.db create mode 100644 src/database/desafio_delphi.db2 create mode 100644 src/database/desafio_delphi_bk.db create mode 100644 "src/imagens/Diagramas t\303\251cnicos.jpg" create mode 100644 src/imagens/add_button.png create mode 100644 src/model/DAO/desafio.model.dao.connection.dfm create mode 100644 src/model/DAO/desafio.model.dao.connection.pas create mode 100644 src/model/implements/desafio.model.implements.connection.pas create mode 100644 src/model/implements/desafio.model.implements.orders.pas create mode 100644 src/model/implements/desafio.model.implements.products.pas create mode 100644 src/model/implements/desafio.model.implements.user.pas create mode 100644 src/model/interfaces/desafio.model.interfaces.category.pas create mode 100644 src/model/interfaces/desafio.model.interfaces.connection.pas create mode 100644 src/model/interfaces/desafio.model.interfaces.order_items.pas create mode 100644 src/model/interfaces/desafio.model.interfaces.orders.pas create mode 100644 src/model/interfaces/desafio.model.interfaces.products.pas create mode 100644 src/model/interfaces/desafio.model.interfaces.user.pas create mode 100644 src/prjDesafioDelphi.dpr create mode 100644 src/prjDesafioDelphi.dproj create mode 100644 src/view/desafio.view.login.dfm create mode 100644 src/view/desafio.view.login.pas create mode 100644 src/view/desafio.view.main.dfm create mode 100644 src/view/desafio.view.main.pas create mode 100644 src/view/desafio.view.register.product.dfm create mode 100644 src/view/desafio.view.register.product.pas create mode 100644 src/view/desafio.view.register.user.dfm create mode 100644 src/view/desafio.view.register.user.pas diff --git a/src/database/desafio_delphi.db b/src/database/desafio_delphi.db new file mode 100644 index 0000000000000000000000000000000000000000..70567a44c3d1f5be8c4fdc1c991be0e548b5c688 GIT binary patch literal 24576 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 PgeI9IH}tTqvvz!hoZZP*^S{G`S9*T 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 H**yL~+%~M+ literal 0 HcmV?d00001 diff --git a/src/model/DAO/desafio.model.dao.connection.dfm b/src/model/DAO/desafio.model.dao.connection.dfm new file mode 100644 index 0000000..672421c --- /dev/null +++ b/src/model/DAO/desafio.model.dao.connection.dfm @@ -0,0 +1,11 @@ +object DMConnection: TDMConnection + Height = 305 + Width = 426 + PixelsPerInch = 120 + object FDConnection1: TFDConnection + Params.Strings = ( + 'DriverID=SQLite') + Left = 160 + Top = 80 + end +end diff --git a/src/model/DAO/desafio.model.dao.connection.pas b/src/model/DAO/desafio.model.dao.connection.pas new file mode 100644 index 0000000..b3601a9 --- /dev/null +++ b/src/model/DAO/desafio.model.dao.connection.pas @@ -0,0 +1,31 @@ +unit desafio.model.dao.connection; + +interface + +uses + System.SysUtils, System.Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option, + FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def, + FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.VCLUI.Wait, + Data.DB, FireDAC.Comp.Client, FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef, + FireDAC.Stan.ExprFuncs, FireDAC.Phys.SQLiteWrapper.Stat, FireDAC.Stan.Param, + FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, FireDAC.Comp.DataSet; + +type + TDMConnection = class(TDataModule) + FDConnection1: TFDConnection; + private + { Private declarations } + public + { Public declarations } + end; + +var + DMConnection: TDMConnection; + +implementation + +{%CLASSGROUP 'Vcl.Controls.TControl'} + +{$R *.dfm} + +end. diff --git a/src/model/implements/desafio.model.implements.connection.pas b/src/model/implements/desafio.model.implements.connection.pas new file mode 100644 index 0000000..d444c87 --- /dev/null +++ b/src/model/implements/desafio.model.implements.connection.pas @@ -0,0 +1,163 @@ +unit desafio.model.implements.connection; + +interface + +uses + desafio.model.interfaces.connection, desafio.model.dao.connection, + FireDAC.Comp.Client, Data.DB, inifiles; + +type + TConnection = class(TInterfacedObject, iConnection) + private + dm : TDMConnection; + FQuery : TFDQuery; + FDataSource : TDataSource; + public + + function sql(aValue : String) : iConnection; + function result : TDataSet; + function datasource : TDataSource; + function query : TFDQuery; + + function open : iConnection; + function close : iConnection; + function exec : iConnection; + function params(aParams : String; aValue : Integer) : iConnection; overload; + function params(aParams : String; aValue : String) : iConnection; overload; + function params(aParams : String; aValue : Currency) : iConnection; overload; + function insert : iConnection; + function cancel : iConnection; + function post : iConnection; + + constructor Create; + destructor Destroy; override; + class function New : iConnection; + end; + +implementation + +uses + System.SysUtils, Vcl.Forms; + +{ TConnection } + +function TConnection.cancel: iConnection; +begin + FQuery.Cancel; + Result := Self; +end; + +function TConnection.close: iConnection; +begin + FQuery.Close; + Result := Self; +end; + +constructor TConnection.Create; + var + iniConf : TIniFile; + vServer, vPath: String; +begin + + iniConf := TIniFile.Create(ExtractFilePath(Application.exeName)+'config.ini'); + try + vPath := iniConf.ReadString('base', 'path', ''); + finally + iniConf.Free; + end; + + dm := TDMConnection.Create(nil); + + dm.FDConnection1.Params.Add('Database='+vPath) ; + + FQuery := TFDQuery.Create(nil); + FQuery.Connection := dm.FDConnection1; + + FDataSource := TDataSource.Create(nil); + FDataSource.DataSet := FQuery; + + +end; + +function TConnection.datasource: TDataSource; +begin + Result := FDataSource; +end; + +destructor TConnection.Destroy; +begin + FDataSource.Free; + FQuery.Free; + dm.Free; + + inherited; +end; + +function TConnection.exec: iConnection; +begin + FQuery.ExecSQL; + Result := Self; +end; + +function TConnection.insert: iConnection; +begin + FQuery.Insert; +end; + +class function TConnection.New: iConnection; +begin + Result := self.Create; +end; + +function TConnection.open: iConnection; +begin + FQuery.Open; + Result := Self; +end; + +function TConnection.params(aParams: String; aValue: Integer): iConnection; +begin + FQuery.ParamByName(aParams).AsInteger := aValue; + Result := self; +end; + +function TConnection.params(aParams: String; aValue: String): iConnection; +begin + FQuery.ParamByName(aParams).AsString := aValue; + Result := self; +end; + + +function TConnection.params(aParams: String; aValue: Currency): iConnection; +begin + FQuery.ParamByName(aParams).AsCurrency := aValue; + Result := self; +end; + +function TConnection.post: iConnection; +begin + FQuery.Post; + Result := Self; +end; + +function TConnection.query: TFDQuery; +begin + result := FQuery; +end; + +function TConnection.result: TDataSet; +begin + Result := FQuery; +end; + +function TConnection.sql(aValue: String): iConnection; +begin + Fquery.Close; + FQuery.SQL.Clear; + FQuery.SQL.Text := aValue; + + Result := Self; +end; + + +end. diff --git a/src/model/implements/desafio.model.implements.orders.pas b/src/model/implements/desafio.model.implements.orders.pas new file mode 100644 index 0000000..67ef812 --- /dev/null +++ b/src/model/implements/desafio.model.implements.orders.pas @@ -0,0 +1,215 @@ +unit desafio.model.implements.orders; + +interface + +uses + desafio.model.interfaces.orders, desafio.model.interfaces.connection, + Data.DB, desafio.model.implements.connection; + + +type + TOrders = class(TInterfacedObject, iOrders) + private + + conn : iConnection; + connView : iConnection; + + FId : Integer; + FProduct : integer; + FTotalValue : Currency; + FTypeMaintenance : Integer; + FCategory : Integer; + + FDateOrder : TDateTime; + + function insert : iOrders; + function cancel : iOrders; + function post(order : iOrders) : iOrders; + + function dataSource : TDataSource; + + function result : TDataSet; + + function searchOrder(aValue : integer) : iOrders; + + function listAllOrders : iOrders; + + function fillObject : iOrders; + + function getId : Integer; + function getTotalValue : Currency; + function getDateOrder : TDateTime; + function getTypeMaintenance : Integer; + function getProduct : Integer; + + procedure setId(aValue : Integer); + procedure setTotalValue(aValue : Currency); + procedure setDateOrder(aValue : TDateTime); + + procedure setTypeMaintenance(aValue : integer); + procedure setProduct(aValue: Integer); + + function viewShowData() : TDataSource; + + public + constructor create; + destructor destroy; override; + class function new : iOrders; + + end; + +implementation + +{ TOrders } + +function TOrders.cancel: iOrders; +begin + conn.result.Cancel; +end; + +constructor TOrders.create; +begin + conn := TConnection.New; +end; + +function TOrders.dataSource: TDataSource; +begin + Result := conn.datasource; +end; + +destructor TOrders.destroy; +begin + //pass + inherited; +end; + +function TOrders.fillObject : iOrders; +begin + FId := conn.result.FieldByName('id').AsInteger; + FProduct := conn.result.FieldByName('product').AsInteger; + FTotalValue := conn.result.FieldByName('total_value').AsCurrency; + FTypeMaintenance := conn.result.FieldByName('type_maintenance').AsInteger; + +end; + +function TOrders.getTotalValue: Currency; +begin + Result := FTotalValue; +end; + +function TOrders.getDateOrder: TDateTime; +begin + Result := FDateOrder; +end; + +function TOrders.getId: Integer; +begin + Result := FId; +end; + +function TOrders.getProduct: Integer; +begin + Result := FProduct; +end; + +function TOrders.getTypeMaintenance: Integer; +begin + Result := FTypeMaintenance; +end; + +function TOrders.insert: iOrders; +begin + conn.result.Insert; + Result := Self; +end; + +function TOrders.listAllOrders: iOrders; +begin + conn.sql('select id, product, quantity, total_value, date_order, type_maintenance '+ + 'from orders') + .open; + + if conn.result.RecordCount > 0 then + begin + fillObject; + end; + + Result := Self; +end; + +class function TOrders.new: iOrders; +begin + Result := self.create; +end; + +function TOrders.post(order : iOrders): iOrders; +begin + conn.result.FieldByName('id').AsInteger := order.getId; + conn.result.FieldByName('total_value').AsCurrency := order.getTotalValue; + conn.result.FieldByName('date_order').AsDateTime := order.getDateOrder; + + conn.result.post; + Result := Self; +end; + +function TOrders.result: TDataSet; +begin + result := conn.result; +end; + +function TOrders.searchOrder(aValue: integer): iOrders; +begin + conn.sql('select id, product, quantity, total_value, date_order '+ + 'from orders where id=:id') + .params('id', aValue) + .open; + + if conn.result.RecordCount > 0 then + begin + FId := conn.result.FieldByName('id').AsInteger; + FTotalValue := conn.result.FieldByName('total_value').AsFloat; + FDateOrder := conn.result.FieldByName('date_order').AsDateTime; + end; + + Result := Self; +end; + +procedure TOrders.setTotalValue(aValue: Currency); +begin + FTotalValue := aValue; +end; + +procedure TOrders.setDateOrder(aValue: TDateTime); +begin + FDateOrder := aValue; +end; + +procedure TOrders.setId(aValue: Integer); +begin + FId := aValue; +end; + +procedure TOrders.setProduct(aValue: Integer); +begin + FProduct := aValue; +end; + +procedure TOrders.setTypeMaintenance(aValue: integer); +begin + FTypeMaintenance := aValue; +end; + +function TOrders.viewShowData: TDataSource; + +begin + connView := TConnection.New; + + connView.sql('select orders.id, trim(products.description) as description, products.sale_price, '+ + 'orders.quantity, orders.total_value, case type_maintenance when 1 THEN "Entrada" ELSE "Saida" END as type_maintenance '+ + 'from orders inner join products on (orders.product=products.id)') + .open; + result := connView.datasource; +end; + +end. + diff --git a/src/model/implements/desafio.model.implements.products.pas b/src/model/implements/desafio.model.implements.products.pas new file mode 100644 index 0000000..43cd762 --- /dev/null +++ b/src/model/implements/desafio.model.implements.products.pas @@ -0,0 +1,248 @@ +unit desafio.model.implements.products; + +interface + +uses + desafio.model.interfaces.products, desafio.model.interfaces.connection, + desafio.model.implements.connection, Data.DB, System.Classes; + +type + TProducts = class(TInterfacedObject, iProducts) + private + conn : iConnection; + + FId : integer; + FDescription : String; + FPriceSell : Currency; + FStorage : Integer; + FCategory: integer; + FPurchasePrice: Currency; + + function dataSource : TDataSource; + function result : TDataSet; + + function searchProducts(aValue : integer) : iProducts; + + function getId : Integer; + function getDescription : String; + function getPriceSell : Currency; + function getPurchasePrice : Currency; + + function getStorage : Double; + function getCategory : Integer; + + procedure setId(aValue : Integer); + procedure setDescription(aValue : String); + procedure setPriceSell(aValue : Currency); + procedure setPurchasePrice(aValue : Currency); + procedure setStorage(aValue : integer); + procedure setCategory(aValue : Integer); + + function listAllProducts: iProducts; + + function fillObject : iProducts; + + function edit(product : iProducts) : iProducts; + + function existProductById(aValue: integer): boolean; + + function strlistAllProducts: string; + + public + + constructor Create; + destructor Destroy; override; + class function New : iProducts; + + end; + +implementation + +uses + System.SysUtils; + +{ TProducts } + +constructor TProducts.Create; +begin + conn := TConnection.New; +end; + +function TProducts.dataSource: TDataSource; +begin + Result := conn.datasource; +end; + +destructor TProducts.Destroy; +begin + //pass + inherited; +end; + +function TProducts.edit(product: iProducts): iProducts; +begin + if existProductById(product.getId) then + begin + conn.sql('update users set '+ + 'description=:description, purchase_price=:purchase_price, '+ + 'sale_price=:sale_price, quantity_stock=:quantity_stock '+ + 'where id=:id ' + ) + .params('id', product.getId) + .params('description', product.getDescription) + .params('purchase_price', product.getPurchasePrice) + .params('sale_price', product.getPriceSell) + .params('quantity_stock', product.getStorage) + .exec; + + searchProducts(product.getId); + end; + + result := self; +end; + +function TProducts.getCategory: Integer; +begin + Result := FCategory; +end; + +function TProducts.getDescription: String; +begin + Result := FDescription; +end; + +function TProducts.getId: Integer; +begin + Result := FId; +end; + +function TProducts.getPriceSell: Currency; +begin + Result := FPriceSell; +end; + +function TProducts.getPurchasePrice: Currency; +begin + Result := FPurchasePrice; +end; + +function TProducts.getStorage: Double; +begin + Result := FStorage; +end; + +class function TProducts.New: iProducts; +begin + result := self.Create; +end; + +function TProducts.result: TDataSet; +begin + result := conn.result; +end; + +function TProducts.searchProducts(aValue: integer): iProducts; +begin + conn.sql('select id, description, purchase_price, sale_price, quantity_stock, category from products where id=:id') + .params('id', aValue) + .open; + + if conn.result.RecordCount > 0 then + begin + fillObject; + end; +end; + +function TProducts.existProductById(aValue: integer): boolean; +begin + conn.sql('select id, description, purchase_price, sale_price, quantity_stock, category from products where id=:id') + .params('id', aValue) + .open; + + result := (conn.result.RecordCount > 0) ; +end; + +function TProducts.fillObject : iProducts; +begin + FId := conn.result.FieldByName('id').AsInteger; + FDescription := conn.result.FieldByName('description').AsString; + FPriceSell := conn.result.FieldByName('sale_price').AsCurrency; + FStorage := conn.result.FieldByName('quantity_stock').AsInteger; + FCategory := conn.result.FieldByName('category').AsInteger; +end; + +procedure TProducts.setCategory(aValue: Integer); +begin + FCategory := aValue; +end; + +procedure TProducts.setDescription(aValue: String); +begin + FDescription := aValue; +end; + +procedure TProducts.setId(aValue: Integer); +begin + FId := aValue; +end; + +procedure TProducts.setPriceSell(aValue: Currency); +begin + FPriceSell := aValue; +end; + +procedure TProducts.setPurchasePrice(aValue: Currency); +begin + FPurchasePrice := aValue; +end; + +procedure TProducts.setStorage(aValue: integer); +begin + FStorage := aValue; +end; + +function TProducts.strlistAllProducts: String; + var + lConn : IConnection; + sProducts : String; +begin + lConn := TConnection.New; + + + lConn.sql('select id, description, purchase_price, sale_price, quantity_stock, category ' + + 'from products') + .open; + + + if lConn.result.RecordCount>0 then + begin + sProducts := ''; + lConn.result.First; + while not lConn.result.Eof do + begin + if trim(sProducts) <> '' then + sProducts := sProducts + ';'; + + sProducts := sProducts + formatFloat('00000',lConn.result.fieldByName('id').AsInteger)+ + '='+ lConn.result.fieldByName('description').AsString; + lConn.result.Next; + end; + + result := sProducts; + end; +end; + +function TProducts.listAllProducts: iProducts; +begin + conn.sql('select id, description, purchase_price, sale_price, quantity_stock, category ' + + 'from products') + .open; + + if conn.result.RecordCount>0 then + fillObject; + + result := self; +end; + +end. + diff --git a/src/model/implements/desafio.model.implements.user.pas b/src/model/implements/desafio.model.implements.user.pas new file mode 100644 index 0000000..f9b19ae --- /dev/null +++ b/src/model/implements/desafio.model.implements.user.pas @@ -0,0 +1,193 @@ +unit desafio.model.implements.user; + +interface + +uses desafio.model.interfaces.user, desafio.model.interfaces.connection, desafio.model.implements.connection; + +type + TUser = class(TInterfacedObject, iUser) + private + conn: iConnection; + + FId: integer; + FName: string; + FEmail: string; + FPassword: string; + + function getId : Integer; + function getName : String; + function getEmail : string; + function getPassword : string; + + procedure setId(aValue : Integer); + procedure setName(aValue : String); + procedure setEmail(aValue : String); + procedure setPassword(aValue : String); + + public + + constructor Create; + destructor Destroy; override; + class function New : iUser; + + function searchUser(aValue: integer): iUser; + function searchUserByEmail(aValue: string) : iUser; + function existUserByEmail(aValue: string): boolean; + function loginUser(aEmail, aPassword : String) : iUser; + function fillObject : iUser; + function insert(user : iUser) : iUser; + + end; + +implementation + +{ TUser } + +constructor TUser.Create; +begin + conn := TConnection.New; +end; + +destructor TUser.Destroy; +begin + //pass + inherited; +end; + + +function TUser.getEmail: string; +begin + Result := FEmail; +end; + +function TUser.getId: Integer; +begin + Result := FId; +end; + +function TUser.getName: String; +begin + Result := FName; +end; + +function TUser.getPassword: string; +begin + Result := FPassword; +end; + +function TUser.insert(user: iUser): iUser; +begin + + if not existUserByEmail(user.getEmail) then + begin + conn.sql('insert into users (name, email, password) '+ + 'values (:name, :email, :password)') + .params('name', user.getName) + .params('email', user.getEmail) + .params('password', user.getPassword) + .exec; + + searchUserByEmail(user.getEmail); + end; + + result := self; +end; + +class function TUser.New: iUser; +begin + result := self.Create; +end; + +procedure TUser.setEmail(aValue: String); +begin + FEmail := aValue; +end; + +procedure TUser.setId(aValue: Integer); +begin + FId := aValue; +end; + +procedure TUser.setName(aValue: String); +begin + FName := aValue; + +end; + +procedure TUser.setPassword(aValue: String); +begin + FPassword := aValue; +end; + +function TUser.searchUser(aValue: integer): iUser; +begin + conn.sql('select id, name, email, password from users where id=:id') + .params('id', aValue) + .open; + + if conn.result.RecordCount > 0 then + begin + FId := conn.result.FieldByName('id').AsInteger; + FName := conn.result.FieldByName('name').AsString; + FEmail := conn.result.FieldByName('email').AsString; + FPassword := conn.result.FieldByName('password').AsString; + end; +end; + +function TUser.searchUserByEmail(aValue: string): iUser; +begin + + FId := 0; + FName := ''; + FEmail := ''; + FPassword := ''; + + conn.sql('select id, name, email, password from users where email=:email') + .params('email', aValue) + .open; + + if conn.result.RecordCount > 0 then + begin + FId := conn.result.FieldByName('id').AsInteger; + FName := conn.result.FieldByName('name').AsString; + FEmail := conn.result.FieldByName('email').AsString; + FPassword := conn.result.FieldByName('password').AsString; + end; +end; + +function TUser.existUserByEmail(aValue: string): boolean; +begin + conn.sql('select id, name, email, password from users where email=:email') + .params('email', aValue) + .open; + + result := (conn.result.RecordCount > 0); +end; + + +function TUser.loginUser(aEmail, aPassword : String): iUser; +begin + result := Nil; + + conn.SQL('select * from users where email=:email and password=:password'); + conn.Params('email', aEmail); + conn.Params('password', aPassword); + conn.Open; + + if not conn.result.IsEmpty then + Result := fillObject; +end; + +function TUser.fillObject: iUser; +begin + Result := TUser.Create; + conn.result.First; + + Result.setId(conn.result.FieldByName('id').AsInteger); + Result.setName(conn.result.FieldByName('name').AsString); + Result.setEmail(conn.result.FieldByName('email').AsString); + Result.setPassword(conn.result.FieldByName('password').AsString); +end; + + +end. diff --git a/src/model/interfaces/desafio.model.interfaces.category.pas b/src/model/interfaces/desafio.model.interfaces.category.pas new file mode 100644 index 0000000..64946ae --- /dev/null +++ b/src/model/interfaces/desafio.model.interfaces.category.pas @@ -0,0 +1,23 @@ +unit desafio.model.interfaces.category; + +interface + +type + +iCategory = interface + + function searchCategory(aValue : integer) : iCategory; + + function getId : Integer; + function getDescription : String; + + procedure setId(aValue : Integer) ; + procedure setDescription(aValue : String) ; + + + end; + + +implementation + +end. diff --git a/src/model/interfaces/desafio.model.interfaces.connection.pas b/src/model/interfaces/desafio.model.interfaces.connection.pas new file mode 100644 index 0000000..6b040c6 --- /dev/null +++ b/src/model/interfaces/desafio.model.interfaces.connection.pas @@ -0,0 +1,29 @@ +unit desafio.model.interfaces.connection; + +interface + + +uses Data.DB, FireDAC.Comp.Client; + +type + iConnection = interface + function sql(aValue : String) : iConnection; + function result : TDataSet; + function datasource : TDataSource; + function query : TFDQuery; + + function open : iConnection; + function close : iConnection; + function exec : iConnection; + function params(aParams : String; aValue : Integer) : iConnection; overload; + function params(aParams : String; aValue : String) : iConnection; overload; + function params(aParams : String; aValue : Currency) : iConnection; overload; + function insert : iConnection; + function cancel : iConnection; + function post : iConnection; + end; + + +implementation + +end. diff --git a/src/model/interfaces/desafio.model.interfaces.order_items.pas b/src/model/interfaces/desafio.model.interfaces.order_items.pas new file mode 100644 index 0000000..ea8d783 --- /dev/null +++ b/src/model/interfaces/desafio.model.interfaces.order_items.pas @@ -0,0 +1,38 @@ +unit desafio.model.interfaces.order_items; + +interface + +uses + Data.DB, FireDAC.Comp.Client; + +type + + iOrder_items = interface + + function dataSource: TDataSource; + + function searchOrder_items(aValue: Integer): iOrder_items; + + function listOrderDetails(dsMaster: TDataSource; + masterFields, indexFieldNames: String): iOrder_items; + + function query: TFDQuery; + + function getId: Integer; + function getIdOrder: Integer; + function getIdProduct: Integer; + function getPriceSell: Currency; + function getQuantity: Integer; + + procedure setId(const Value: Integer); + procedure setIdOrder(const Value: Integer); + procedure setIdProduct(const Value: Integer); + procedure setPriceSell(const Value: Currency); + procedure setQuantity(const Value: Integer); + + end; + + +implementation + +end. diff --git a/src/model/interfaces/desafio.model.interfaces.orders.pas b/src/model/interfaces/desafio.model.interfaces.orders.pas new file mode 100644 index 0000000..57b6d5d --- /dev/null +++ b/src/model/interfaces/desafio.model.interfaces.orders.pas @@ -0,0 +1,44 @@ +unit desafio.model.interfaces.orders; + +interface + +uses + Data.DB; + +type + iOrders = interface + + function insert : iOrders; + function cancel : iOrders; + function post(order : iOrders) : iOrders; + + function dataSource : TDataSource; + + function result : TDataSet; + + function searchOrder(aValue : integer) : iOrders; + + function listAllOrders : iOrders; + + function fillObject : iOrders; + + function getId : Integer; + function getTotalValue : Currency; + function getDateOrder : TDateTime; + function getTypeMaintenance : Integer; + function getProduct : Integer; + + + procedure setId(aValue : Integer); + procedure setTotalValue(aValue : Currency); + procedure setDateOrder(aValue : TDateTime); + procedure setTypeMaintenance(aValue : integer); + procedure setProduct(aValue: Integer); + + function viewShowData: TDataSource; + + end; + +implementation + +end. diff --git a/src/model/interfaces/desafio.model.interfaces.products.pas b/src/model/interfaces/desafio.model.interfaces.products.pas new file mode 100644 index 0000000..95ea580 --- /dev/null +++ b/src/model/interfaces/desafio.model.interfaces.products.pas @@ -0,0 +1,45 @@ +unit desafio.model.interfaces.products; + +interface + +uses + Data.DB, System.Classes; + +type + iProducts = interface + + function dataSource : TDataSource; + function result : TDataSet; + + function searchProducts(aValue : integer) : iProducts; + function listAllProducts: iProducts; + function fillObject : iProducts; + + function getId : Integer; + function getDescription : String; + function getStorage : Double; + function getPriceSell : Currency; + function getPurchasePrice : Currency; + function getCategory : Integer; + + procedure setId(aValue : Integer) ; + procedure setDescription(aValue : String) ; + procedure setStorage(aValue : Integer); + procedure setPriceSell(aValue : Currency) ; + procedure setPurchasePrice(aValue : Currency); + procedure setCategory(aValue : Integer); + + function existProductById(aValue: integer): boolean; + function strlistAllProducts : string; + + + end; + + +implementation + +end. +n + +uses + System.Classes; diff --git a/src/model/interfaces/desafio.model.interfaces.user.pas b/src/model/interfaces/desafio.model.interfaces.user.pas new file mode 100644 index 0000000..06b5efc --- /dev/null +++ b/src/model/interfaces/desafio.model.interfaces.user.pas @@ -0,0 +1,28 @@ +unit desafio.model.interfaces.user; + +interface + +type + + iUser = interface + + function getId : Integer; + function getName : String; + function getEmail : string; + function getPassword : string; + + procedure setId(aValue : Integer); + procedure setName(aValue : String); + procedure setEmail(aValue : String); + procedure setPassword(aValue : String); + + function loginUser(aEmail, aPassword : String) : iUser; + function insert(user : iUser) : iUser; + + end; + + + +implementation + +end. diff --git a/src/prjDesafioDelphi.dpr b/src/prjDesafioDelphi.dpr new file mode 100644 index 0000000..9e6dd88 --- /dev/null +++ b/src/prjDesafioDelphi.dpr @@ -0,0 +1,29 @@ +program prjDesafioDelphi; + +uses + Vcl.Forms, + desafio.view.main in 'view\desafio.view.main.pas' {frmMain}, + desafio.view.login in 'view\desafio.view.login.pas' {frmLogin}, + desafio.model.interfaces.products in 'model\interfaces\desafio.model.interfaces.products.pas', + desafio.model.interfaces.category in 'model\interfaces\desafio.model.interfaces.category.pas', + desafio.model.interfaces.orders in 'model\interfaces\desafio.model.interfaces.orders.pas', + desafio.model.interfaces.connection in 'model\interfaces\desafio.model.interfaces.connection.pas', + desafio.model.interfaces.order_items in 'model\interfaces\desafio.model.interfaces.order_items.pas', + desafio.model.interfaces.user in 'model\interfaces\desafio.model.interfaces.user.pas', + desafio.model.implements.user in 'model\implements\desafio.model.implements.user.pas', + desafio.model.implements.connection in 'model\implements\desafio.model.implements.connection.pas', + desafio.model.dao.connection in 'model\DAO\desafio.model.dao.connection.pas' {DMConnection: TDataModule}, + desafio.view.register.user in 'view\desafio.view.register.user.pas' {frmRegisterUser}, + desafio.model.implements.orders in 'model\implements\desafio.model.implements.orders.pas', + desafio.model.implements.products in 'model\implements\desafio.model.implements.products.pas', + desafio.view.register.product in 'view\desafio.view.register.product.pas' {frmRegisterProduct}; + +{$R *.res} + +begin + Application.Initialize; + Application.MainFormOnTaskbar := True; + ReportMemoryLeaksOnShutdown := true; + Application.CreateForm(TfrmMain, frmMain); + Application.Run; +end. diff --git a/src/prjDesafioDelphi.dproj b/src/prjDesafioDelphi.dproj new file mode 100644 index 0000000..e9d679a --- /dev/null +++ b/src/prjDesafioDelphi.dproj @@ -0,0 +1,999 @@ + + + {B9A98A53-2F7F-46D9-AF0D-664465D7BAA2} + 19.5 + VCL + True + Debug + Win32 + 1 + Application + prjDesafioDelphi.dpr + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + prjDesafioDelphi + + + soapserver;IndySystem;vclwinx;fmx;vclie;DbxCommonDriver;bindengine;vcldb;IndyIPCommon;VCLRESTComponents;FireDACCommonODBC;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;IndyIPClient;dbxcds;vcledge;vclFireDAC;bindcompvclwinx;bindcomp;FireDACCommon;IndyCore;RESTBackendComponents;bindcompfmx;bindcompdbx;inetdb;rtl;FireDACMySQLDriver;FireDACSqliteDriver;DbxClientDriver;FireDACADSDriver;RESTComponents;soapmidas;DBXSqliteDriver;vcl;vclactnband;IndyIPServer;dsnapxml;fmxFireDAC;dbexpress;dsnapcon;adortl;DBXMySQLDriver;VclSmp;inet;vclimg;vcltouch;FireDACPgDriver;FireDAC;fmxase;inetdbxpress;xmlrtl;tethering;dbrtl;bindcompvcl;dsnap;fmxdae;CloudService;FireDACMSAccDriver;CustomIPTransport;fmxobj;bindcompvclsmp;soaprtl;vcldsnap;DBXInterBaseDriver;FireDACIBDriver;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + $(BDS)\bin\default_app.manifest + + + soapserver;IndySystem;vclwinx;fmx;vclie;DbxCommonDriver;bindengine;vcldb;IndyIPCommon;VCLRESTComponents;FireDACCommonODBC;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;IndyIPClient;dbxcds;vcledge;vclFireDAC;bindcompvclwinx;bindcomp;FireDACCommon;IndyCore;RESTBackendComponents;bindcompfmx;bindcompdbx;inetdb;rtl;FireDACMySQLDriver;FireDACSqliteDriver;DbxClientDriver;FireDACADSDriver;RESTComponents;soapmidas;DBXSqliteDriver;vcl;vclactnband;IndyIPServer;dsnapxml;fmxFireDAC;dbexpress;dsnapcon;adortl;DBXMySQLDriver;VclSmp;inet;vclimg;vcltouch;FireDACPgDriver;FireDAC;fmxase;inetdbxpress;xmlrtl;tethering;dbrtl;bindcompvcl;dsnap;fmxdae;CloudService;FireDACMSAccDriver;CustomIPTransport;fmxobj;bindcompvclsmp;soaprtl;vcldsnap;DBXInterBaseDriver;FireDACIBDriver;$(DCC_UsePackage) + + + DEBUG;$(DCC_Define) + true + false + true + true + true + true + true + + + false + PerMonitorV2 + true + 1033 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + PerMonitorV2 + + + + MainSource + + +
frmMain
+ dfm +
+ +
frmLogin
+ dfm +
+ + + + + + + + + +
DMConnection
+ dfm + TDataModule +
+ +
frmRegisterUser
+ dfm +
+ + + +
frmRegisterProduct
+ dfm +
+ + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + +
+ + Delphi.Personality.12 + Application + + + + prjDesafioDelphi.dpr + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + prjDesafioDelphi.exe + true + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen + 64 + + + ..\$(PROJECTNAME).launchscreen + 64 + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + + + + + + + + + + + + True + False + + + 12 + + + + +
diff --git a/src/view/desafio.view.login.dfm b/src/view/desafio.view.login.dfm new file mode 100644 index 0000000..f6d5c62 --- /dev/null +++ b/src/view/desafio.view.login.dfm @@ -0,0 +1,180 @@ +object frmLogin: TfrmLogin + Left = 0 + Top = 0 + Caption = 'Desafio Delphi - Khipo' + ClientHeight = 390 + ClientWidth = 551 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Segoe UI' + Font.Style = [] + Position = poScreenCenter + TextHeight = 15 + object Panel1: TPanel + Left = 0 + Top = 0 + Width = 551 + Height = 97 + Align = alTop + BevelOuter = bvNone + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + Padding.Left = 30 + Padding.Top = 30 + Padding.Right = 30 + Padding.Bottom = 10 + ParentFont = False + TabOrder = 0 + ExplicitWidth = 628 + object Label1: TLabel + Left = 30 + Top = 30 + Width = 491 + Height = 23 + Align = alTop + Caption = 'Usu'#225'rio' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + ParentFont = False + ExplicitWidth = 58 + end + object edEmail: TEdit + Left = 30 + Top = 56 + Width = 491 + Height = 31 + Align = alBottom + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + ParentFont = False + TabOrder = 0 + Text = 'lauro@gmail.com' + ExplicitTop = 96 + ExplicitWidth = 568 + end + end + object Panel3: TPanel + Left = 0 + Top = 244 + Width = 551 + Height = 146 + Align = alBottom + BevelOuter = bvNone + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + Padding.Left = 30 + Padding.Top = 30 + Padding.Right = 30 + Padding.Bottom = 10 + ParentFont = False + TabOrder = 2 + ExplicitTop = 296 + ExplicitWidth = 628 + object Button1: TButton + Left = 270 + Top = 30 + Width = 130 + Height = 106 + Align = alRight + Caption = 'Entrar' + TabOrder = 0 + OnClick = Button1Click + ExplicitLeft = 392 + ExplicitTop = 31 + ExplicitHeight = 104 + end + object Button2: TButton + Left = 400 + Top = 30 + Width = 121 + Height = 106 + Align = alRight + Caption = 'Cadastrar' + TabOrder = 1 + OnClick = Button2Click + ExplicitLeft = 464 + ExplicitTop = 31 + ExplicitHeight = 104 + end + object Button3: TButton + Left = 30 + Top = 30 + Width = 122 + Height = 106 + Align = alLeft + Caption = 'Cancelar' + TabOrder = 2 + OnClick = Button3Click + ExplicitLeft = 87 + ExplicitTop = 39 + ExplicitHeight = 104 + end + end + object Panel2: TPanel + Left = 0 + Top = 97 + Width = 551 + Height = 97 + Align = alTop + BevelOuter = bvNone + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + Padding.Left = 30 + Padding.Top = 30 + Padding.Right = 30 + Padding.Bottom = 10 + ParentFont = False + TabOrder = 1 + ExplicitTop = 8 + ExplicitWidth = 628 + object Label2: TLabel + Left = 30 + Top = 30 + Width = 491 + Height = 23 + Align = alTop + Caption = 'Senha' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + ParentFont = False + ExplicitWidth = 47 + end + object edPassword: TEdit + Left = 30 + Top = 56 + Width = 491 + Height = 31 + Align = alBottom + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + ParentFont = False + PasswordChar = '*' + TabOrder = 0 + Text = '123' + ExplicitWidth = 568 + end + end +end diff --git a/src/view/desafio.view.login.pas b/src/view/desafio.view.login.pas new file mode 100644 index 0000000..8abec40 --- /dev/null +++ b/src/view/desafio.view.login.pas @@ -0,0 +1,66 @@ +unit desafio.view.login; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, + Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls; + +type + TfrmLogin = class(TForm) + Panel1: TPanel; + Panel3: TPanel; + Button1: TButton; + Button2: TButton; + Button3: TButton; + edEmail: TEdit; + Label1: TLabel; + Panel2: TPanel; + Label2: TLabel; + edPassword: TEdit; + procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); + procedure Button3Click(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +var + frmLogin: TfrmLogin; + +implementation + +uses desafio.view.register.user; + +{$R *.dfm} + +procedure TfrmLogin.Button1Click(Sender: TObject); +begin + ModalResult := mrOk; +end; + +procedure TfrmLogin.Button2Click(Sender: TObject); +var + lRegisterUser: TfrmRegisterUser; +begin + lRegisterUser:= TfrmRegisterUser.Create(nil); + try + lRegisterUser.ShowModal; + if lRegisterUser.ModalResult = mrOk then + begin + self.edEmail.Text := lRegisterUser.edtEmail.Text; + self.edPassword.Text := lRegisterUser.edtPassword.Text; + end; + finally + FreeAndNil(lRegisterUser); + end; +end; + +procedure TfrmLogin.Button3Click(Sender: TObject); +begin + close; +end; + +end. diff --git a/src/view/desafio.view.main.dfm b/src/view/desafio.view.main.dfm new file mode 100644 index 0000000..baa713f --- /dev/null +++ b/src/view/desafio.view.main.dfm @@ -0,0 +1,302 @@ +object frmMain: TfrmMain + Left = 0 + Top = 0 + Caption = 'Desafio Delphi - Khipo' + ClientHeight = 503 + ClientWidth = 824 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Segoe UI' + Font.Style = [] + Position = poScreenCenter + OnCreate = FormCreate + TextHeight = 15 + object Panel1: TPanel + Left = 0 + Top = 65 + Width = 824 + Height = 72 + Align = alTop + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + Padding.Left = 10 + Padding.Top = 20 + Padding.Right = 10 + Padding.Bottom = 10 + ParentFont = False + TabOrder = 0 + ExplicitWidth = 818 + object Label1: TLabel + Left = 11 + Top = 21 + Width = 167 + Height = 40 + Align = alLeft + Caption = 'Tipo de manuten'#231#227'o: ' + ExplicitHeight = 23 + end + object cbTypeMaintenance: TComboBox + Left = 196 + Top = 21 + Width = 461 + Height = 31 + TabOrder = 0 + Text = '--Tipo de manuten'#231#227'o (Entrada/Sa'#237'da)--' + end + end + object Panel2: TPanel + Left = 0 + Top = 137 + Width = 824 + Height = 63 + Align = alTop + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + Padding.Left = 10 + Padding.Top = 20 + Padding.Right = 20 + Padding.Bottom = 10 + ParentFont = False + TabOrder = 1 + ExplicitWidth = 818 + object Panel6: TPanel + Left = 11 + Top = 21 + Width = 185 + Height = 31 + Align = alLeft + BevelOuter = bvNone + TabOrder = 0 + object Label2: TLabel + Left = 0 + Top = 0 + Width = 71 + Height = 31 + Align = alLeft + Caption = 'Produto: ' + ExplicitHeight = 23 + end + end + object Panel7: TPanel + Left = 196 + Top = 21 + Width = 461 + Height = 31 + Align = alLeft + BevelOuter = bvNone + TabOrder = 1 + object btAddProduct: TButton + Left = 417 + Top = 0 + Width = 44 + Height = 31 + Align = alRight + Caption = '+' + TabOrder = 0 + OnClick = btAddProductClick + end + object dbcbProducts: TComboBox + Left = 0 + Top = 0 + Width = 417 + Height = 31 + Align = alClient + TabOrder = 1 + Text = '--Lista de Produtos--' + OnChange = dbcbProductsChange + end + end + object Panel8: TPanel + Left = 657 + Top = 21 + Width = 185 + Height = 31 + Align = alLeft + BevelOuter = bvNone + Padding.Left = 20 + TabOrder = 2 + object lbProductValue: TLabel + Left = 20 + Top = 0 + Width = 70 + Height = 31 + Align = alLeft + Caption = 'R$ 0,00 ' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -20 + Font.Name = 'Segoe UI' + Font.Style = [] + ParentFont = False + ExplicitHeight = 28 + end + end + end + object Panel3: TPanel + Left = 0 + Top = 0 + Width = 824 + Height = 65 + Align = alTop + BevelOuter = bvNone + Padding.Left = 10 + Padding.Top = 20 + Padding.Right = 10 + Padding.Bottom = 10 + TabOrder = 2 + ExplicitWidth = 818 + object DBNavOrders: TDBNavigator + Left = 10 + Top = 20 + Width = 804 + Height = 35 + Align = alClient + TabOrder = 0 + OnClick = DBNavOrdersClick + ExplicitWidth = 798 + end + end + object Panel5: TPanel + Left = 0 + Top = 200 + Width = 824 + Height = 65 + Align = alTop + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + Padding.Left = 10 + Padding.Top = 20 + Padding.Right = 10 + Padding.Bottom = 10 + ParentFont = False + TabOrder = 3 + ExplicitWidth = 818 + object Label4: TLabel + Left = 11 + Top = 21 + Width = 94 + Height = 33 + Align = alLeft + Caption = 'Quantidade:' + ExplicitHeight = 23 + end + object dbeQuantity: TDBEdit + Left = 200 + Top = 16 + Width = 121 + Height = 31 + TabOrder = 0 + OnExit = dbeQuantityExit + end + object Panel9: TPanel + Left = 613 + Top = 21 + Width = 200 + Height = 33 + Align = alRight + BevelOuter = bvNone + TabOrder = 1 + ExplicitLeft = 607 + object lbTotalOrder: TLabel + Left = 0 + Top = 0 + Width = 200 + Height = 33 + Align = alClient + Caption = 'Total: R$ ' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -20 + Font.Name = 'Segoe UI' + Font.Style = [] + ParentFont = False + ExplicitWidth = 79 + ExplicitHeight = 28 + end + end + end + object Panel4: TPanel + Left = 0 + Top = 264 + Width = 824 + Height = 239 + Align = alBottom + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + Padding.Left = 10 + Padding.Top = 20 + Padding.Right = 10 + Padding.Bottom = 20 + ParentFont = False + TabOrder = 4 + ExplicitTop = 255 + ExplicitWidth = 818 + object Label3: TLabel + Left = 11 + Top = 21 + Width = 802 + Height = 23 + Align = alTop + Caption = 'Historico de transa'#231#245'es:' + ExplicitWidth = 181 + end + object DBGOrders: TDBGrid + Left = 11 + Top = 44 + Width = 802 + Height = 174 + Align = alClient + TabOrder = 0 + TitleFont.Charset = DEFAULT_CHARSET + TitleFont.Color = clWindowText + TitleFont.Height = -17 + TitleFont.Name = 'Segoe UI' + TitleFont.Style = [] + Columns = < + item + Expanded = False + Width = 50 + Visible = True + end + item + Expanded = False + Width = 300 + Visible = True + end + item + Expanded = False + Width = 100 + Visible = True + end + item + Expanded = False + Width = 100 + Visible = True + end + item + Expanded = False + Width = 100 + Visible = True + end + item + Expanded = False + Width = 100 + Visible = True + end> + end + end +end diff --git a/src/view/desafio.view.main.pas b/src/view/desafio.view.main.pas new file mode 100644 index 0000000..66dd262 --- /dev/null +++ b/src/view/desafio.view.main.pas @@ -0,0 +1,291 @@ +unit desafio.view.main; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, + Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.DBCtrls, Vcl.ExtCtrls, + Data.DB, Vcl.Grids, Vcl.DBGrids, Vcl.Mask; + +type + TfrmMain = class(TForm) + Panel1: TPanel; + Label1: TLabel; + Panel2: TPanel; + Panel3: TPanel; + DBNavOrders: TDBNavigator; + Panel5: TPanel; + Label4: TLabel; + dbeQuantity: TDBEdit; + Panel4: TPanel; + DBGOrders: TDBGrid; + Panel6: TPanel; + Panel7: TPanel; + Label2: TLabel; + Panel8: TPanel; + lbProductValue: TLabel; + btAddProduct: TButton; + dbcbProducts: TComboBox; + cbTypeMaintenance: TComboBox; + Panel9: TPanel; + lbTotalOrder: TLabel; + Label3: TLabel; + procedure FormCreate(Sender: TObject); + procedure btAddProductClick(Sender: TObject); + procedure DBNavOrdersClick(Sender: TObject; Button: TNavigateBtn); + procedure dbcbProductsChange(Sender: TObject); + procedure dbeQuantityExit(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + + function userValidation(aEmail, aPassword: String): Boolean; + procedure fillComboProducts; + procedure setRowComboProduct(idProduct: Integer); + + function priceSetProduct(idProduct : integer) : Currency; + procedure updateValuesInScreen(); + end; + +var + frmMain: TfrmMain; + +implementation + +uses desafio.view.login, desafio.model.interfaces.user, desafio.model.implements.user, + desafio.model.interfaces.orders, desafio.model.implements.orders, + desafio.model.interfaces.products, desafio.model.implements.products, + desafio.view.register.product; + +var + lUser : iUser; + lOrders : iOrders; + lProducts : iProducts; + + +{$R *.dfm} + +procedure TfrmMain.btAddProductClick(Sender: TObject); + var + lRegisterProduct: TfrmRegisterProduct; +begin + lRegisterProduct := TfrmRegisterProduct.create(nil); + + try + + lRegisterProduct.ShowModal; + + DBcbProducts.Items.Clear; + DBcbProducts.Items.Delimiter := ';'; + DBcbProducts.Items.StrictDelimiter := true; + DBcbProducts.Items.DelimitedText := lProducts.strlistAllProducts; + + finally + lRegisterProduct.Free; + end; + +end; + +procedure TfrmMain.FormCreate(Sender: TObject); +var + lLogin: TfrmLogin; + loginProcess : boolean; +begin + lLogin := TfrmLogin.create(nil); + try + + loginProcess := true; + + while loginProcess do + begin + + lLogin.ShowModal; + + try + if not (lLogin.ModalResult = mrOk) then + begin + loginProcess := false; + Application.Terminate; + end + else if userValidation(lLogin.edEmail.Text, lLogin.edPassword.Text) then + begin + loginProcess := false; + end + else + showmessage('Usuario não autenticado'); + except + showmessage('Houve um erro, verifique os arquivos de configuração.'); + Application.Terminate; + end; + end; + + if Assigned(lUser) then + begin + if lUser.getId>0 then + begin + + lOrders := TOrders.new; + lProducts := TProducts.new; + + lProducts.listAllProducts; + + lOrders.listAllOrders; + + DBNavOrders.DataSource := lOrders.dataSource; + + cbTypeMaintenance.items.clear; + cbTypeMaintenance.items.Delimiter:= ';'; + cbTypeMaintenance.items.StrictDelimiter := true; + cbTypeMaintenance.Items.DelimitedText := 'Entrada;Saída'; + + fillComboProducts; + + DBGOrders.DataSource := lOrders.viewShowData; + + DBGOrders.Columns[0].FieldName := 'id'; + DBGOrders.Columns[1].FieldName := 'description'; + DBGOrders.Columns[2].FieldName := 'sale_price'; + DBGOrders.Columns[3].FieldName := 'quantity'; + DBGOrders.Columns[4].FieldName := 'total_value'; + DBGOrders.Columns[5].FieldName := 'type_maintenance'; + + DBGOrders.ReadOnly := true; + + dbeQuantity.DataField := 'quantity'; + dbeQuantity.DataSource := lOrders.dataSource; + + cbTypeMaintenance.ItemIndex := lOrders.getTypeMainTenance; + + setRowComboProduct(lOrders.getProduct); + + updateValuesInScreen(); + + end; + end; + + finally + lLogin.Free; + end; + +end; + +procedure TfrmMain.setRowComboProduct(idProduct: Integer); + var + lProductInCombo : iProducts; + idToFind : String; + idFound : Integer; +begin + lProductInCombo := TProducts.New; + lProductInCombo.searchProducts(idProduct) ; + + if lProductInCombo.getId > 0 then + begin + idToFind := formatFloat('00000',lProductInCombo.getId); + + idToFind := idToFind + '=' +lProductInCombo.getDescription; + idFound := DBcbProducts.Items.IndexOf(idToFind); + DBcbProducts.ItemIndex := idFound ; + lbProductValue.Caption := 'R$ '+formatfloat('#,###0.00',lProductInCombo.getPriceSell); + end; + +end; + +procedure TfrmMain.dbcbProductsChange(Sender: TObject); +begin + updateValuesInScreen(); +end; + +procedure TfrmMain.dbeQuantityExit(Sender: TObject); +begin + updateValuesInScreen(); +end; + +procedure TfrmMain.updateValuesInScreen(); + var + iIdProduct : Integer; + lQuantity : Double; + lpriceSetProduct : Currency; +begin + + lQuantity := 0; + + iIdProduct := strToIntDef(copy(dbcbProducts.Text,0,5),0); + + lpriceSetProduct := priceSetProduct(iIdProduct) ; + + lQuantity := strToFloatDef(trim(dbeQuantity.Text),0) ; + + if lQuantity>0 then + lbTotalOrder.caption := 'Total: R$ '+ formatFloat('#,###,##0.00',lpriceSetProduct * lQuantity); + + lbProductValue.Caption := 'R$ '+formatFloat('#,###,##0.00',lpriceSetProduct); +end; + +function TfrmMain.priceSetProduct(idProduct : integer) : Currency; + var + lProductRefreshPrice : iProducts; +begin + lProductRefreshPrice := TProducts.New; + + lProductRefreshPrice.searchProducts(idProduct); + + result := lProductRefreshPrice.getPriceSell; +end; + + +procedure TfrmMain.DBNavOrdersClick(Sender: TObject; Button: TNavigateBtn); +begin + if Button in [nbInsert] then + begin + cbTypeMaintenance.ItemIndex := -1; + dbcbProducts.ItemIndex := -1; + lbProductValue.Caption := 'R$ 0,00'; + lbTotalOrder.Caption := 'Total: R$ 0,00'; + end + else if Button in [nbCancel] then + begin + setRowComboProduct(lOrders.getProduct); + updateValuesInScreen; + end + else if Button in [nbFirst, nbPrior, nbNext, nbLast] then + begin + lOrders.fillObject; + cbTypeMaintenance.ItemIndex := lOrders.getTypeMainTenance-1; + setRowComboProduct(lOrders.getProduct); + updateValuesInScreen; + end + else if Button in [nbPost] then + begin + lOrders.result.Edit; + lOrders.result.FieldByName('type_maintenance').AsInteger := cbTypeMaintenance.ItemIndex+1; + lOrders.result.FieldByName('product').AsInteger := StrToIntDef(copy(dbcbProducts.Text, 0, 5),0); + lOrders.result.FieldByName('total_value').AsCurrency := priceSetProduct(StrToIntDef(copy(dbcbProducts.Text, 0, 5),0))*strtointdef(DBEQUANTITY.Text,0); + lOrders.result.Post; + lOrders.fillObject; + DBGOrders.DataSource := lOrders.viewShowData; + end; + +end; + +procedure TfrmMain.fillComboProducts; +begin + DBcbProducts.Items.Clear; + DBcbProducts.Items.Delimiter := ';'; + DBcbProducts.Items.StrictDelimiter := true; + DBcbProducts.Items.DelimitedText := lProducts.strlistAllProducts; +end; + +function TfrmMain.userValidation(aEmail, aPassword: String): Boolean; +begin + lUser := TUser.new; + + lUser := lUser.LoginUser(aEmail, aPassword); + + if not Assigned(lUser) then + Result := False + else + Result := not lUser.getId.ToString.IsEmpty; +end; + +end. diff --git a/src/view/desafio.view.register.product.dfm b/src/view/desafio.view.register.product.dfm new file mode 100644 index 0000000..c14f301 --- /dev/null +++ b/src/view/desafio.view.register.product.dfm @@ -0,0 +1,245 @@ +object frmRegisterProduct: TfrmRegisterProduct + Left = 0 + Top = 0 + Caption = 'Desafio Delphi - Khipo' + ClientHeight = 442 + ClientWidth = 784 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Segoe UI' + Font.Style = [] + Position = poScreenCenter + OnCreate = FormCreate + TextHeight = 15 + object Panel3: TPanel + Left = 0 + Top = 65 + Width = 784 + Height = 377 + Align = alClient + BevelOuter = bvNone + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + ParentFont = False + TabOrder = 0 + ExplicitWidth = 778 + ExplicitHeight = 368 + object Panel4: TPanel + Left = 10 + Top = 10 + Width = 764 + Height = 87 + Align = alTop + BevelOuter = bvNone + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + TabOrder = 0 + object Label1: TLabel + Left = 10 + Top = 10 + Width = 744 + Height = 23 + Align = alTop + Caption = 'Descri'#231#227'o' + ExplicitWidth = 73 + end + object edDescription: TEdit + Left = 10 + Top = 46 + Width = 744 + Height = 31 + Align = alBottom + TabOrder = 0 + Text = 'edDescription' + OnChange = edDescriptionChange + ExplicitTop = 71 + ExplicitWidth = 738 + end + end + object Panel5: TPanel + AlignWithMargins = True + Left = 10 + Top = 100 + Width = 764 + Height = 89 + Margins.Left = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alTop + BevelOuter = bvNone + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + TabOrder = 1 + ExplicitTop = 156 + ExplicitWidth = 758 + object Panel1: TPanel + Left = 10 + Top = 10 + Width = 279 + Height = 69 + Align = alLeft + BevelOuter = bvNone + Padding.Right = 10 + TabOrder = 0 + object Label2: TLabel + Left = 0 + Top = 0 + Width = 269 + Height = 23 + Align = alTop + Caption = 'Pre'#231'o de compra' + ExplicitWidth = 130 + end + object dbedPurchasePrice: TDBEdit + Left = 0 + Top = 38 + Width = 269 + Height = 31 + Align = alBottom + ImeName = 'Japanese' + TabOrder = 0 + end + end + object Panel7: TPanel + Left = 289 + Top = 10 + Width = 307 + Height = 69 + Align = alLeft + BevelOuter = bvNone + Padding.Right = 10 + TabOrder = 1 + object Label4: TLabel + Left = 0 + Top = 0 + Width = 297 + Height = 23 + Align = alTop + Caption = 'Pre'#231'o de venda' + ExplicitWidth = 118 + end + object dbedSalePrice: TDBEdit + Left = 0 + Top = 38 + Width = 297 + Height = 31 + Align = alBottom + ImeName = 'Japanese' + TabOrder = 0 + end + end + end + object Panel6: TPanel + AlignWithMargins = True + Left = 10 + Top = 192 + Width = 764 + Height = 75 + Margins.Left = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alTop + BevelOuter = bvNone + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + TabOrder = 2 + ExplicitTop = 248 + ExplicitWidth = 758 + object Panel8: TPanel + Left = 289 + Top = 10 + Width = 307 + Height = 55 + Align = alLeft + BevelOuter = bvNone + Padding.Right = 10 + TabOrder = 0 + object Label3: TLabel + Left = 0 + Top = 0 + Width = 297 + Height = 23 + Align = alTop + Caption = 'Categoria' + ExplicitWidth = 74 + end + object dbedCategory: TDBEdit + Left = 0 + Top = 24 + Width = 297 + Height = 31 + Align = alBottom + ImeName = 'Japanese' + TabOrder = 0 + end + end + object Panel9: TPanel + Left = 10 + Top = 10 + Width = 279 + Height = 55 + Align = alLeft + BevelOuter = bvNone + Padding.Right = 10 + TabOrder = 1 + object Label5: TLabel + Left = 0 + Top = 0 + Width = 269 + Height = 23 + Align = alTop + Caption = 'Quantidade' + ExplicitWidth = 90 + end + object dbedQuantity: TDBEdit + Left = 0 + Top = 24 + Width = 269 + Height = 31 + Align = alBottom + ImeName = 'Japanese' + TabOrder = 0 + end + end + end + end + object pNavProducts: TPanel + Left = 0 + Top = 0 + Width = 784 + Height = 65 + Align = alTop + Caption = 'pNavProducts' + Padding.Left = 10 + Padding.Top = 20 + Padding.Right = 10 + Padding.Bottom = 10 + TabOrder = 1 + ExplicitWidth = 778 + object dbNavProducts: TDBNavigator + Left = 11 + Top = 21 + Width = 762 + Height = 33 + Align = alClient + TabOrder = 0 + OnClick = dbNavProductsClick + ExplicitWidth = 756 + end + end +end diff --git a/src/view/desafio.view.register.product.pas b/src/view/desafio.view.register.product.pas new file mode 100644 index 0000000..72afa83 --- /dev/null +++ b/src/view/desafio.view.register.product.pas @@ -0,0 +1,118 @@ +unit desafio.view.register.product; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, + Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.DBCtrls, + Vcl.Mask; + +type + TfrmRegisterProduct = class(TForm) + Panel3: TPanel; + Panel4: TPanel; + Label1: TLabel; + Panel5: TPanel; + Panel6: TPanel; + Panel1: TPanel; + Label2: TLabel; + Panel7: TPanel; + Label4: TLabel; + Panel8: TPanel; + Label3: TLabel; + Panel9: TPanel; + Label5: TLabel; + pNavProducts: TPanel; + dbNavProducts: TDBNavigator; + dbedPurchasePrice: TDBEdit; + dbedSalePrice: TDBEdit; + dbedQuantity: TDBEdit; + dbedCategory: TDBEdit; + edDescription: TEdit; + procedure FormCreate(Sender: TObject); + procedure dbNavProductsClick(Sender: TObject; Button: TNavigateBtn); + procedure dbedDescriptionExit(Sender: TObject); + procedure edDescriptionChange(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +var + frmRegisterProduct: TfrmRegisterProduct; + +implementation + +uses + desafio.model.interfaces.products, desafio.model.implements.products, + Data.DB; + +var + lProducts : iProducts; + +{$R *.dfm} + +procedure TfrmRegisterProduct.dbedDescriptionExit(Sender: TObject); +begin + if dbNavProducts.DataSource.State in [DsBrowse] then + begin + edDescription.Text := lProducts.getDescription; + end +end; + +procedure TfrmRegisterProduct.dbNavProductsClick(Sender: TObject; + Button: TNavigateBtn); +begin + if Button in [nbInsert] then + begin + edDescription.Text := ''; + end + else if Button in [nbCancel] then + begin + edDescription.Text := lProducts.getDescription; + end + else if Button in [nbFirst, nbPrior, nbNext, nbLast] then + begin + lProducts.fillObject; + edDescription.Text := lProducts.getDescription; + end + else if Button in [nbPost] then + begin + + lProducts.result.Edit; + lProducts.result.FieldByName('description').AsString := edDescription.Text; + lProducts.result.Post; + lProducts.fillObject; + end; + + +end; + +procedure TfrmRegisterProduct.edDescriptionChange(Sender: TObject); +begin + lProducts.dataSource.Edit; +end; + +procedure TfrmRegisterProduct.FormCreate(Sender: TObject); +begin + + lProducts := TProducts.New ; + + lProducts.listAllProducts ; + + dbNavProducts.DataSource := lProducts.dataSource; + dbedPurchasePrice.DataSource := lProducts.dataSource; + dbedSalePrice.DataSource := lProducts.dataSource; + dbedQuantity.DataSource := lProducts.dataSource; + dbedCategory.DataSource := lProducts.dataSource; + + dbedPurchasePrice.DataField := 'purchase_price'; + dbedSalePrice.DataField := 'sale_price'; + dbedQuantity.DataField := 'quantity_stock'; + dbedCategory.DataField := 'category'; + + edDescription.Text := lProducts.getDescription; +end; + +end. diff --git a/src/view/desafio.view.register.user.dfm b/src/view/desafio.view.register.user.dfm new file mode 100644 index 0000000..03c5441 --- /dev/null +++ b/src/view/desafio.view.register.user.dfm @@ -0,0 +1,199 @@ +object frmRegisterUser: TfrmRegisterUser + Left = 0 + Top = 0 + Caption = 'Desafio Delphi - Khipo' + ClientHeight = 442 + ClientWidth = 628 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Segoe UI' + Font.Style = [] + Position = poScreenCenter + TextHeight = 15 + object Panel2: TPanel + Left = 0 + Top = 336 + Width = 628 + Height = 106 + Align = alBottom + BevelOuter = bvNone + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + ParentFont = False + TabOrder = 0 + object Button1: TButton + Left = 10 + Top = 10 + Width = 158 + Height = 86 + Align = alLeft + Caption = 'Salvar' + TabOrder = 0 + OnClick = Button1Click + ExplicitLeft = 3 + ExplicitTop = 3 + ExplicitHeight = 92 + end + end + object Panel3: TPanel + Left = 0 + Top = 0 + Width = 628 + Height = 336 + Align = alClient + BevelOuter = bvNone + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -17 + Font.Name = 'Segoe UI' + Font.Style = [] + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + ParentFont = False + TabOrder = 1 + ExplicitLeft = 8 + ExplicitTop = 8 + ExplicitWidth = 381 + ExplicitHeight = 174 + object Panel4: TPanel + Left = 10 + Top = 10 + Width = 608 + Height = 75 + Align = alTop + BevelOuter = bvNone + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + TabOrder = 0 + object Label1: TLabel + Left = 10 + Top = 10 + Width = 588 + Height = 23 + Align = alTop + Caption = 'Nome' + ExplicitLeft = 0 + ExplicitTop = 0 + ExplicitWidth = 47 + end + object edtName: TEdit + Left = 10 + Top = 36 + Width = 588 + Height = 29 + Align = alBottom + BevelInner = bvNone + BevelOuter = bvNone + Ctl3D = False + ImeName = 'Japanese' + ParentCtl3D = False + TabOrder = 0 + ExplicitLeft = 0 + ExplicitTop = 29 + ExplicitWidth = 608 + end + end + object Panel5: TPanel + AlignWithMargins = True + Left = 10 + Top = 88 + Width = 608 + Height = 75 + Margins.Left = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alTop + BevelOuter = bvNone + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + TabOrder = 1 + object Label2: TLabel + Left = 10 + Top = 10 + Width = 588 + Height = 23 + Align = alTop + Caption = 'E-mail' + ExplicitLeft = 0 + ExplicitTop = 0 + ExplicitWidth = 48 + end + object edtemail: TEdit + Left = 10 + Top = 36 + Width = 588 + Height = 29 + Align = alBottom + BevelInner = bvNone + BevelOuter = bvNone + Ctl3D = False + ParentCtl3D = False + TabOrder = 0 + ExplicitLeft = 0 + ExplicitTop = 29 + ExplicitWidth = 608 + end + end + object Panel6: TPanel + AlignWithMargins = True + Left = 10 + Top = 166 + Width = 608 + Height = 75 + Margins.Left = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alTop + BevelOuter = bvNone + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + TabOrder = 2 + ExplicitTop = 180 + object Label3: TLabel + Left = 10 + Top = 10 + Width = 588 + Height = 23 + Align = alTop + Caption = 'Senha' + ExplicitLeft = 0 + ExplicitTop = 0 + ExplicitWidth = 47 + end + object edtPassword: TEdit + Left = 10 + Top = 36 + Width = 588 + Height = 29 + Align = alBottom + BevelInner = bvNone + BevelOuter = bvNone + Ctl3D = False + ImeName = 'Japanese' + ParentCtl3D = False + PasswordChar = '*' + TabOrder = 0 + ExplicitLeft = 0 + ExplicitTop = 29 + ExplicitWidth = 608 + end + end + end +end diff --git a/src/view/desafio.view.register.user.pas b/src/view/desafio.view.register.user.pas new file mode 100644 index 0000000..a626932 --- /dev/null +++ b/src/view/desafio.view.register.user.pas @@ -0,0 +1,65 @@ +unit desafio.view.register.user; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, + Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls; + +type + TfrmRegisterUser = class(TForm) + Panel2: TPanel; + Button1: TButton; + Panel3: TPanel; + Panel4: TPanel; + Label1: TLabel; + edtName: TEdit; + Panel5: TPanel; + Label2: TLabel; + edtemail: TEdit; + Panel6: TPanel; + Label3: TLabel; + edtPassword: TEdit; + procedure Button1Click(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +var + frmRegisterUser: TfrmRegisterUser; + +implementation + +uses + desafio.model.interfaces.user, desafio.model.implements.user; + +{$R *.dfm} + + +procedure TfrmRegisterUser.Button1Click(Sender: TObject); + var + lUser : iUser; + +begin + lUser := TUser.new; + + lUser.setId(0); + lUser.setName(edtName.Text); + lUser.setEmail(edtEmail.Text); + lUser.setPassword(edtPassword.Text); + + lUser.insert(lUser); + + if lUser.getId > 0 then + begin + showmessage('Usuário inserido com sucesso') ; + modalResult := mrOk; + end + else + showmessage('Houve um erro na inserção deste usuário'); + +end; + +end. From fc3f9a16d82401ccba3c546aabc8d4f30d3aae33 Mon Sep 17 00:00:00 2001 From: Wagner Inaba Date: Sat, 9 Mar 2024 06:16:25 -0300 Subject: [PATCH 2/2] Update README.md --- README.md | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/README.md b/README.md index 90ed000..35c6363 100644 --- a/README.md +++ b/README.md @@ -62,3 +62,58 @@ Desenvolver uma aplicação em Delphi que simule um sistema de gerenciamento de - Testes e documentação. Boa sorte com o desafio! Estamos animados para ver o que você pode criar. + + +---------------------------------------------------------------------------- + +## - Solução proposta: + +Foi desenvolvido um sistema para entrada e saida de produtos + +Fluxograma da solução + +![Diagramas técnicos](https://github.com/winaba/desafio-delphi/assets/17182623/9d1b9d47-60ef-4746-9d3c-27ed1d01973f) + + +Composto por: +- telas de Login, +- cadastro de usuario, +- entrada e saida de produtos, +- cadastro de produtos + +Ao abrir o sistema é apresentado a tela de login: + +![Captura de tela 2024-03-09 031242](https://github.com/winaba/desafio-delphi/assets/17182623/e37e77fd-d421-472f-9c55-d029268fbd6e) + + +Caso não possua usuario, é necessario cadastra-lo no botão 'Cadastrar' + +![Captura de tela 2024-03-09 031328](https://github.com/winaba/desafio-delphi/assets/17182623/33e715f1-b734-4fc4-93e8-8e8d57a22e24) + + +Depois de possuir o cadastro e se logar, será apresentado a tela de entrada e saída de prdoutos + +![Captura de tela 2024-03-09 031959](https://github.com/winaba/desafio-delphi/assets/17182623/4ec5fbcb-7ecf-4557-afba-34bc86bdc4f5) + +Caso no momento do cadastro da movimentação o produto não esteja disponivel, clique no botão '+' + +![Captura de tela 2024-03-09 032032](https://github.com/winaba/desafio-delphi/assets/17182623/46ddf955-c97c-406a-b624-931e8849ed45) + + +Configuração + +Para rodar a aplicação é necerio tem um arquivo ini ```config.ini``` configurado no mesmo diretório que o exe + +Exemplo: + +``` +[base] +path=E:\estudos\delphi\desafio_khipo2\desafio-delphi\src\database\desafio_delphi.db +``` +Banco de dados + +O banco de dados utilizado nesta aplicação foi o SQLite + +há exemplos de banco de dados em 'src/database' + +