Invoice::setDueDate() must implement interface DateTimeInterface, Xero API using calcinai

hungrykoala picture hungrykoala · Sep 9, 2016 · Viewed 11.1k times · Source

I am following this wrapper

I have this error: Catchable fatal error: Argument 1 passed to XeroPHP\Models\Accounting\Invoice::setDueDate() must implement interface DateTimeInterface, string given

This is my code:

try{
            $lineitem = new LineItem($this->_xi);
            $lineitem->setAccountCode('200')
            ->setQuantity('5.400')
            ->setDescription('this is awesome test')
            ->setUnitAmount('9900.00');

            $contact = new Contact($this->_xi);
            $contact->setName("John Doe")
                ->setFirstName("John")
                ->setLastName("Doe")
                ->setEmailAddress("[email protected]")
                ->setContactStatus(Contact::CONTACT_STATUS_ACTIVE);



            $invoice = new Invoice($this->_xi);
            $invoice->setType(Invoice::INVOICE_TYPE_ACCREC)
                ->setStatus(Invoice::INVOICE_STATUS_AUTHORISED)
                ->setContact($contact)
                //->setDate(\DateTimeInterface::format("Y-m-d"))
                ->setDueDate("2018-09-09")
                ->setLineAmountType(Invoice::LINEAMOUNT_TYPE_EXCLUSIVE)
                ->addLineItem($lineitem)
                ->setInvoiceNumber('10')
                ->save();



        }catch ( Exception $e ){
            $GLOBALS['log']->fatal('[Xero-createContact]-' . $e->getMessage());
            echo $e->getMessage();

        }

When I tried doing it like this:

->setDueDate(\DateTimeInterface::format("Y-m-d"))

I got this error instead: Fatal error: Non-static method DateTimeInterface::format() cannot be called statically, assuming $this from incompatible context

This is the function of setDueDate that I am calling:

 /**
     * @param \DateTimeInterface $value
     * @return Invoice
     */
public function setDueDate(\DateTimeInterface $value)
    {
        $this->propertyUpdated('DueDate', $value);
        $this->_data['DueDate'] = $value;
        return $this;
    }

I'm really lost here as to how do I use this DateTimeInterface and how can I even set a future date using it, and how do I solve all this errors.

Answer

Akos K picture Akos K · Sep 9, 2016

The first error says, that the ->setDueDate($date) method expects an object which implements the DateTimeInterface, but you supplied just a string instead ->setDueDate("2018-09-09")

The second error says, that the format($format) method cannot be called statically. It expects a format pattern, and formats an existing object to a string according to the pattern provided. However you tried to call it statically, providing the date string instead of the format pattern - no wonder it failed. You need the createFromFormat($format, $date_string) method, which creates a DateTime object from a string, not the other way around.

The solution is to create an object that implements the DateTimeInterface. For example DateTime or DateTimeImmutable (which is the same, but is never modified). I suggest DateTime if you may modify this value later on.

So change this line:

->setDueDate("2018-09-09")

to this:

->setDueDate(\DateTime::createFromFormat('Y-m-d', "2018-09-09"))

and it should work like a charm.