Jump to:

22996 Posts in 11620 Topics by 2826 members

General Questions

SilverStripe Forums » General Questions » Copying Dataobjects (solved sort of)

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 386 Views
  • cumquat
    Avatar
    Community Member
    189 Posts

    Copying Dataobjects (solved sort of) Link to this post

    Any got some pointers for me, I have 4 dataobjects, QuoteHeader and QuoteDetail, OrderHeader and OrderDetail (the order tables are copies of their quote counterparts with a couple of extra fields)

    QuoteHeader has_many QuoteDetails.
    OrderHeader has_many OrderDetails.

    This is all good and i have a couple of forms that create the QuoteHeader and then the QuoteDetails, so far so good.
    What I want to do now is create a function that on the click of a button it copies the QuoteHeader info to an OrderHeader dataobject and then an QuoteDetails to an OrderDetails dataobject.

    Has anyone created a similar function i can look at to tweak for my needs?

    Cheers
    Mick

  • Sean
    Avatar
    Forum Moderator
    921 Posts

    Re: Copying Dataobjects (solved sort of) Link to this post

    In the context of a Form object, you can always do things like

    $quote = new QuoteHeader();
    $form->saveInto($quote);

    That will save the form contents into the DataObject, provided the names of the field match up to fields on the DataObject's $db definition.

    If you wanted to copy a DataObject to another, provided the fields are the same names, you might do something like this:

    $data = QuoteHeader::get()->byId(1)->toMap();
    $order = new OrderHeader();
    $order->update($data);
    $order->write();

    toMap() returns the internal DataObjects array of db fields and their values, which you can pass into update() called on a new instance of OrderHeader to effectively copy the fields across.

    Hopefully that's of some help.

    Sean

  • cumquat
    Avatar
    Community Member
    189 Posts

    Re: Copying Dataobjects (solved sort of) Link to this post

    Hi Sean,

    Thanks for getting back to me, the copying of the dataobject is the way i want to go as i have currently two forms one for header and then one for adding the details. i have tried the code below, without much success, and as ever no error messages it just doesn't seem to make the copy.
    I notices when i printed the contents of the array is doesn't list the data for the attached has_many relation is that correct or would you expect that function to copy both the header and details fields and copy those to their respected dataobjects.

    function doaddOrder(){
    $quote = QuoteHeader::get()->byId(2)->toMap();

    $order = new OrderHeader();

    $order->update($quote);
    //print_r($order);

    $order->write();
    // Controller::curr()->redirectBack();
    }


    class QuoteHeader extends DataObject {

       public static $db = array(
    'Seq' => 'Int',
    'QuoteNum' => 'Varchar(20)',
    'Date' => 'Date',
    'ExpiryDate' => 'Date',
    'QuoteBy' => 'Varchar(30)',
    'Notes' => 'Text',
    'Status' => 'Varchar(20)'
             
       );
       

       public static $has_many =array (
       'QuoteDetails' => 'QuoteDetail'
       );

    ----------------------

    class QuoteDetail extends DataObject {

       public static $db = array(
    'PartNum' => 'Varchar()',
    'Name' => 'Varchar()',
    'Qty' => 'int',
    'Price' => 'Currency',
    'Total' => 'Currency'
       );
       public static $has_one =array (
          'QuoteHeader' => 'QuoteHeader'
       );


    class OrderHeader extends DataObject {

       public static $db = array(
    'Seq' => 'Int',
    'OrderNum' => 'Varchar(20)',
    'Date' => 'Date',
    'ExpiryDate' => 'Date',
    'OrderBy' => 'Varchar(30)',
    'Notes' => 'Text',
    'Status' => 'Varchar(20)',

             
       );
       

       public static $has_many =array (
       'OrderDetails' => 'OrderDetail'
       );

    -------------------------------
    class OrderDetail extends DataObject {

       public static $db = array(
    'PartNum' => 'Varchar()',
    'Name' => 'Varchar()',
    'Qty' => 'int',
    'Price' => 'Currency',
    'Total' => 'Currency'
       );
       public static $has_one =array (
          'OrderHeader' => 'OrderHeader'
       );

  • martimiz
    Avatar
    Forum Moderator
    1035 Posts

    Re: Copying Dataobjects (solved sort of) Link to this post

    I'm not sure, but it's worth a try: when you map the quoteheader and feed it into the new order, the Orders ID probably gets the value of the QuoteHeader ID as well. Normally the write function will insert if the objects ID is empty, and update on an existing ID.

    At this point no record with that ID exists in the OrderHeader table, so it cannot be updated. You could try to set $order->ID = '' before writing. Or, if you want to keep the same ID, set forceInsert to true?

    [edit]
    write() will not create copies of the details automatically, but write() will return the ID of the newly created order, which you can then use to link a copy of the details to the correct order...

  • cumquat
    Avatar
    Community Member
    189 Posts

    Re: Copying Dataobjects (solved sort of) Link to this post

    Cheers for response.
    I couldn't get the mapping to work so ended up having to sort it manually for now so i can move forward, code below.

    function doaddOrder(){
    $theID = $this->request->getVar('quote');

    $quote = QuoteHeader::get()->byId($theID);
    $submission = new OrderHeader();
    $submission->Seq = $quote->Seq;
    $submission->Date = $quote->Date;
    $submission->Notes = $quote->Notes;
    $submission->QuoteID = $quote->ID;
    $submission->CustomerID = $quote->CustomerID;
    $submission->DeliveryID = $quote->DeliveryID;
    $submission->InvoiceID = $quote->InvoiceID;
    $submission->ContactID = $quote->ContactID;
    $submission ->write();

    $QuoteItems = QuoteDetail::get()->filter('QuoteHeaderID' , $theID);
    foreach($QuoteItems as $QuoteItem){
    $sub = new OrderDetail();
    $sub->PartNum = $QuoteItem->PartNum;
    $sub->Name = $QuoteItem->Name;
    $sub->Qty = $QuoteItem->Qty;
    $sub->Price = $QuoteItem->Price;
    $sub->Total = $QuoteItem->Total;
    $sub->OrderHeaderID = $submission->ID;
    $sub->write();

    }
    Controller::curr()->redirectBack();
    }

    386 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.