unit BusinessObjects; // *************************************************************************** } // // Delphi MVC Framework // // Copyright (c) 2010-2022 Daniele Teti and the DMVCFramework Team // // https://github.com/danieleteti/delphimvcframework // // *************************************************************************** // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // *************************************************************************** interface uses MVCFramework.Serializer.Commons, MVCFramework.ActiveRecord, MVCFramework.Nullables, System.Generics.Collections, System.Classes; type [MVCNameCase(ncCamelCase)] [MVCTable('articles')] TArticles = class(TMVCActiveRecord) private [MVCTableField('id', [foPrimaryKey, foAutoGenerated])] fID: Int64; [MVCTableField('description')] fDescription: String; [MVCTableField('price')] fPrice: Integer; public constructor Create; override; destructor Destroy; override; property ID: Int64 read fID write fID; property Description: String read fDescription write fDescription; property Price: Integer read fPrice write fPrice; end; [MVCNameCase(ncCamelCase)] [MVCTable('order_details')] TOrderDetail = class(TMVCActiveRecord) private [MVCTableField('id', [foPrimaryKey, foAutoGenerated])] fID: NullableInt64; [MVCTableField('id_order')] fIDOrder: Int64; [MVCTableField('id_article')] fIDArticle: Int64; [MVCTableField('unit_price')] fUnitPrice: Currency; [MVCTableField('discount')] fDiscount: Integer; [MVCTableField('quantity')] fQuantity: Integer; [MVCTableField('description')] fDescription: String; [MVCTableField('total')] fTotal: Currency; public constructor Create; override; destructor Destroy; override; procedure Assign(Value: TMVCActiveRecord); override; property ID: NullableInt64 read fID write fID; [MVCDoNotSerialize] property IDOrder: Int64 read fIDOrder write fIDOrder; property IDArticle: Int64 read fIDArticle write fIDArticle; property UnitPrice: Currency read fUnitPrice write fUnitPrice; property Discount: Integer read fDiscount write fDiscount; property Quantity: Integer read fQuantity write fQuantity; property Description: String read fDescription write fDescription; property Total: Currency read fTotal write fTotal; end; [MVCNameCase(ncCamelCase)] [MVCTable('orders')] TOrder = class(TMVCActiveRecord) private [MVCTableField('id', [foPrimaryKey, foAutoGenerated])] fID: Int64; [MVCTableField('id_customer')] fIDCustomer: Integer; [MVCTableField('order_date')] fOrderDate: TDate; [MVCTableField('total')] fTotal: Currency; [MVCOwned] fDetails: TObjectList; protected procedure OnAfterLoad; override; procedure OnAfterUpdate; override; procedure OnAfterInsert; override; public constructor Create; override; destructor Destroy; override; function GetOrderDetailByID(const Value: Int64): TOrderDetail; property ID: Int64 read fID write fID; [MVCNameAs('idCustomer')] property IDCustomer: Integer read fIDCustomer write fIDCustomer; property OrderDate: TDate read fOrderDate write fOrderDate; property Total: Currency read fTotal write fTotal; property OrderItems: TObjectList read fDetails; end; implementation uses System.SysUtils; constructor TArticles.Create; begin inherited Create; end; destructor TArticles.Destroy; begin inherited; end; procedure TOrderDetail.Assign(Value: TMVCActiveRecord); var lObj: TOrderDetail; begin if Value is TOrderDetail then begin lObj := TOrderDetail(Value); self.ID := lObj.ID; self.IDOrder := lObj.IDOrder; self.IDArticle := lObj.IDArticle; self.UnitPrice := lObj.UnitPrice; self.Discount := lObj.Discount; self.Quantity := lObj.Quantity; self.Description := lObj.Description; self.Total := lObj.Total; end else begin inherited; end; end; constructor TOrderDetail.Create; begin inherited Create; end; destructor TOrderDetail.Destroy; begin inherited; end; constructor TOrder.Create; begin inherited Create; fDetails := TObjectList.Create(true); end; destructor TOrder.Destroy; begin fDetails.Free; inherited; end; function TOrder.GetOrderDetailByID(const Value: Int64): TOrderDetail; var lOrderDetail: TOrderDetail; begin inherited; for lOrderDetail in fDetails do begin if lOrderDetail.ID.Value = Value then begin Exit(lOrderDetail); end; end; raise EMVCActiveRecord.Create('Item not found'); end; procedure TOrder.OnAfterInsert; var lOrderDetail: TOrderDetail; begin inherited; for lOrderDetail in fDetails do begin lOrderDetail.IDOrder := ID; lOrderDetail.Insert; end; end; procedure TOrder.OnAfterUpdate; var lOrderItems: TObjectList; begin inherited; lOrderItems := TMVCActiveRecord.SelectRQL(Format('eq(idorder,%d)', [ID]), 100); try TMVCActiveRecord.Merge(lOrderItems, fDetails) .Apply( procedure (const Obj: TOrderDetail; const EntityAction: TMVCEntityAction; var Handled: Boolean) begin if EntityAction in [eaCreate, eaUpdate] then begin Obj.IDOrder := ID; end; end); finally lOrderItems.Free; end; end; procedure TOrder.OnAfterLoad; var lList: TObjectList; begin inherited; lList := TMVCActiveRecord.SelectRQL(Format('eq(idOrder,%d)',[ID]), 1000); try fDetails.Clear; fDetails.AddRange(lList); lList.OwnsObjects := False; finally lList.Free; end; end; end.