<?php

namespace Tests\Services\OrderService\GetUpdateOrderModelByWMSOrderHeadersTest;

use App\Batch;
use App\Logistic;
use App\OracleBasCode;
use App\OracleDOCOrderHeader;
use App\Order;
use App\Owner;
use App\Services\OrderService;
use App\Shop;
use App\Warehouse;
use Tests\TestCase;

class GetUpdateModelByWmsOrderHeadersTest extends TestCase
{
    /**
     * @var OrderService $service
     */
    private $service;
    private $data = [];

    public function setUp(): void
    {
        parent::setUp();
        $this->service = app('OrderService');
        $owners = factory(Owner::class)->times(10)->create();
        $logistics = factory(Logistic::class)->times(20)->create();
        $wareHouses = factory(Warehouse::class)->times(3)->create();
        $shops = collect();
        foreach ($owners as $owner) {
            $shops = $shops->concat(factory(Shop::class)->times(rand(3,5))->create(['owner_id'=>$owner->id]));
        }
        $batches = factory(Batch::class)->times(10)->create();
        $orders = collect();
        $orderHeaders = collect();
        foreach ($owners as $owner) {
            $count = rand(2,10);
            for ($i =0 ;$i<=$count;$i++){
                $shop = $shops->where('owner_id',$owner->id)->random();
                $warehouse = $wareHouses->random();
                $logistic = $logistics->random();
                $batch = $batches->random();

                $orderHeader = factory(OracleDOCOrderHeader::class)->make([
                        'warehouseid'=>$warehouse->code,
                        'waveno'=>$batch->code,
                        'customerid'=>$owner->code,
                        'userdefine1'=>$logistic->code,
                        'issuepartyname' => $shop->name,
                    ]);
                $oracleBASCode = factory(OracleBasCode::class)->make();
                $orderType = factory(OracleBasCode::class)->make();
                $orderHeader->setRelation('oracleBASCode',$oracleBASCode);
                $orderHeader->setRelation('orderType',$orderType);
                $orderHeaders = $orderHeaders->push($orderHeader);

                $order = factory(Order::class)->create([
                    'code' => $orderHeader->orderno,
                    'batch_id' =>$batch->id,
                    'warehouse_id' => $warehouse->id,
                    'logistic_id' => $logistic->id,
                    'shop_id' => $shop->id,
                    'owner_id' => $owner->id
                ]);
                $orders->push($order);
            }
        }
        $this->data = [
            'warehouses' => $wareHouses,
            'batches' => $batches,
            'owners' => $owners,
            'logistics' => $logistics,
            'shops' => $shops,
            'orders' => $orders,
            'orderHeaders' => $orderHeaders
        ];
    }

    /**
     * @test 测试
     */
    public function getUpdateModelByWmsOrderHeader()
    {
        $update_models = $this->service->getUpdateOrderModelByWMSOrderHeaders(
            $this->data['orderHeaders'],
            $this->data['orders'],
            $this->data['warehouses'],
            $this->data['owners'],
            $this->data['logistics'],
            $this->data['shops'],
            $this->data['batches']
        );
        $this->assertEquals($update_models->count(),count($this->data['orders']));
        $this->assertEquals(count($this->data['orders']),count($update_models));
    }

    /**
     * @test 部分Order与OrderHeaders相同
     */
    public function orderPortionIsEquals()
    {
        $orders  = $this->data['orders']->random(10);
        foreach ($orders as $order) {
            $orderHeader = $this->data['orderHeaders']->where('orderno',$order->code)->first();
            $orderHeader->oracleBASCode->codename_c = '订单完成';
            $order->update([
                'consignee_name' => $orderHeader['c_contact'],
                'consignee_phone' =>$orderHeader['c_tel2'] ?? $orderHeader['c_tel1'] ,
                'province' =>$orderHeader['c_province'] ,
                'city' =>$orderHeader['c_city'] ,
                'district' =>$orderHeader['c_district'] ,
                'address' => $orderHeader['c_address1'],
                'client_code' =>$orderHeader['soreference1'] ,
                'wms_edittime' => $orderHeader['edittime'] ,
                'wms_status' =>$orderHeader->oracleBASCode->codename_c?? "",
                'order_type' =>$orderHeader->orderType->codename_c?? "",
                'created_at' =>  $orderHeader['addtime'],
            ]);
        }
        $orders = Order::query()->whereIn('code',data_get($this->data['orderHeaders'],'*.orderno'))->get();
        $update_params = $this->service->getUpdateOrderModelByWMSOrderHeaders(
            $this->data['orderHeaders'],
            $orders,
            $this->data['warehouses'],
            $this->data['owners'],
            $this->data['logistics'],
            $this->data['shops'],
            $this->data['batches']
        );
        $this->assertEquals($update_params->count(),$orders->count());
        $this->assertOrderHeadersAndUpdateParams($this->data['orderHeaders'],$update_params);
    }

    public function assertOrderHeadersAndUpdateParams($orderHeaders,$update_params){
        foreach ($update_params as $update_param) {
            $warehouse = Warehouse::find($update_param['warehouse_id']);
            $batch = Batch::find($update_param['batch_id']);
            $owner = Owner::find($update_param['owner_id']);
            $logistic = Logistic::find($update_param['logistic_id']);
            $shop = Shop::find($update_param['shop_id']);
            $orderHeader = $orderHeaders->where('orderno',$update_param['code'])->first();
            $this->assertNotEmpty($orderHeader);
            $this->assertEquals($orderHeader['warehouseid'], $warehouse->code);
            $this->assertEquals($orderHeader['waveno'],$batch->code);
            $this->assertEquals($orderHeader['customerid'],$owner->code);
            $this->assertEquals($orderHeader['userdefine1'],$logistic->code);
            $this->assertEquals($orderHeader['issuepartyname'],$shop->name);
            $this->assertEquals($orderHeader->oracleBASCode->codename_c ?? '',$update_param['wms_status']);
            $this->assertEquals($orderHeader->orderType->codename_c ?? '',$update_param['order_type']);
        }
    }

    protected function tearDown(): void
    {
        Order::query()->whereIn('code',data_get($this->data['orderHeaders'],'*.orderno'))->delete();
        Warehouse::destroy(data_get($this->data['warehouses'],'*.id'));
        Batch::destroy(data_get($this->data['batches'],'*.id'));
        Owner::destroy(data_get($this->data['owners'],'*.id'));
        Logistic::destroy(data_get($this->data['logistics'],'*.id'));
        Shop::destroy(data_get($this->data['shops'],'*.id'));
        parent::tearDown(); // TODO: Change the autogenerated stub
    }


}
