retailcrm / api-client-php

PHP client for RetailCRM API
http://www.retailcrm.ru
MIT License
61 stars 60 forks source link

New order method lose customer info #108

Closed warendmir closed 3 years ago

warendmir commented 3 years ago

Hi. I wrote code that create customers before orders. So i know that ID. When i try to send new order and fill customer property, that lose somewhere in request classes and come to crm empty, so crm think that this is new customer.

Using SerializedRelationCustomer class like in docs.

After many debugs im tryed to use default Customer class, and it`s work fine.

Oh and maybe it helps, i`m not use guzzle / psr7 cause it has problems with other my libraries ((, instead of this i use nyholm / psr7

warendmir commented 3 years ago

This is how object before ->getBody() looks like: [customer] => RetailCrm\Api\Model\Entity\Orders\SerializedRelationCustomer Object ( [type] => customer [nickName] => [id] => 97 [externalId] => [browserId] => [site] => [companies] => ) And this is how it looks in JSON after ->getBody(): "customer":{}

Neur0toxine commented 3 years ago

Hi. Can you please provide a code sample that we can use to reproduce the issue?

warendmir commented 3 years ago

Project based on Yii2 Read two comments in function. I cant represent whole code cause it will be to long, you can fill propertyes like you want. I think its not hard.

public function sendOrder( $data, $print=false) {

    list($order_model, $phone, $firstname, $lastname) = $data;
    $request = new OrdersCreateRequest();
    $order = new Order();
    $payment = new Payment();
    $delivery = new SerializedOrderDelivery();
    $deliveryAddress = new OrderDeliveryAddress();

    $cart = json_decode($order_model->cart_json, 1);
    $payment->type = 'payment-' . $order_model->type_payment;
    $payment->status = self::CRM_PAY_STATUSES[$order_model->status??0];

    $deliveryAddress->countryIso = CountryCodeIso3166::UKRAINE;
    $deliveryAddress->city = $order_model->city;
    $deliveryAddress->street = $order_model->street;
    $deliveryAddress->building = $order_model->house_number;
    if ($order_model->apartment_number) {
        $deliveryAddress->flat = $order_model->apartment_number;
    }
    if ($order_model->floor) {
        $deliveryAddress->floor = $order_model->floor;
    }
    if ($order_model->entrance) {
        $deliveryAddress->block = $order_model->entrance;
    }

    $delivery->address = $deliveryAddress;
    $delivery->cost = 0;
    $delivery->netCost = 0;
    $items = [];
    foreach ($cart as $id => $product) {
        $offer = new Offer();
        $offer->name = $product['title'];
        $offer->displayName = $product['title'];
        $offer->externalId = 'o-'.$id;

        $item = new OrderProduct();
        $item->offer = $offer;
        $item->externalId = $id;
        $item->initialPrice = $product['price'];
        $item->productName = $product['title'];
        $item->priceType = new PriceType('base');
        $item->quantity = $product['quantity'];
        $item->purchasePrice = $product['price'];
        $items[] = $item;
    }

    $order->delivery = $delivery;
    $order->number = Yii::$app->params['CRM']['order_number'].'-'.$order_model->id;
    $order->externalId = $order_model->id;
    $order->items = $items;
    $order->payments = [$payment];
    $order->countryIso = CountryCodeIso3166::UKRAINE;
    $order->firstName = $firstname;
    $order->lastName = $lastname;
    $order->phone = $phone;
    if ($order_model->order_comment){
        $order->customerComment = $order_model->order_comment;
    }

    //THIS NOT WORK. WHEN REQUEST - IT WILL BE CLEANED

    if ($this->retailcrm_id) {
        $order->customer = SerializedRelationCustomer::withId(
            $this->retailcrm_id
        );
    } else {
        $order->customer = SerializedRelationCustomer::withExternalId(
            $this->id
        );
        $order->customer->site = Yii::$app->params['CRM']['site'];
    }

    //THIS WORKS

    $order->customer = new Customer();
    if ($this->retailcrm_id) {
        $order->customer->id =$this->retailcrm_id;
    } else {
        $order->customer->externalId =$this->id;
        $order->customer->site = Yii::$app->params['CRM']['site'];
    }

    $order->status = 'new';
    $order->shipmentStore = 'warehouse-' . $order_model->warehouse;
    $order->shipped = false;
    $request->order = $order;
    $request->site = Yii::$app->params['CRM']['site'];

    try {
        $response = $this->client->orders->create($request);
    } catch (ApiExceptionInterface $exception) {
        if ($print) {
            echo sprintf(
                'Error from RetailCRM API (status code: %d): %s',
                $exception->getStatusCode(),
                $exception->getMessage()
            );

            if (count(is_array($exception->getErrorResponse()->errors)?$exception->getErrorResponse()->errors:[]) > 0) {
                echo PHP_EOL . 'Errors: ' . implode(', ', $exception->getErrorResponse()->errors);
            }
            die;
        } else {
            Yii::debug(sprintf(
                'Error from RetailCRM API (status code: %d): %s',
                $exception->getStatusCode(),
                $exception->getMessage()
            ));
            if (count(is_array($exception->getErrorResponse()->errors)?$exception->getErrorResponse()->errors:[]) > 0) {
                Yii::debug(PHP_EOL . 'Errors: ' . implode(', ', $exception->getErrorResponse()->errors));
            }
        }
        return;
    }
    if ($print)
        printf(
            'Created order id = %d with following data: %s',
            $response->id,
            print_r($response->order, true)
        );
}