<?php

namespace Tests\Services\OrderService;

use App\Commodity;
use App\Logistic;
use App\OracleActAllocationDetails;
use App\OracleBasCode;
use App\OracleBasSKU;
use App\OracleDOCOrderDetail;
use App\OracleDOCOrderHeader;
use App\Order;
use App\OrderPackage;
use App\OrderPackageCommodities;
use App\Owner;
use App\Services\OracleBasSkuService;
use App\Services\OrderService;
use App\Shop;
use App\Warehouse;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class CreateOrFindOrderInfoTest extends TestCase
{

    /**
     * @var OrderService $orderService
     */
    public $orderService;
    private $data = [];

    public function setUp(): void
    {
        parent::setUp(); // TODO: Change the autogenerated stub
        $this->orderService = app('OrderService');

        $wmsOrderHeader = factory(OracleDOCOrderHeader::class)->make([
            'customerid'=>'TEST_OW','sostatus'=>99,'userdefine1'=>'TEST_CA','warehouseid'=>'WH_TEST'
        ]);
        $this->data['warehouse']    = factory(Warehouse::class)->create(['code'=>'WH_TEST']);
        $this->data['logistic']     = factory(Logistic::class)->create(['code'=>'TEST_CA','name'=>'测试承运商']);
        $this->data['owner']        = factory(Owner::class)->create(['code'=>'TEST_OW','name'=>'测试货主']);
        $this->data['shop']         = factory(Shop::class)->create(['owner_id'=>$this->data['owner']['id']]);

        $code_BasCode  = factory(OracleBasCode::class)->make(['codeid'=>'OW','code'=>'99','descr_c'=>'订单完成']);
        $orderType = factory(OracleBasCode::class)->make(['code'=>'sysy', 'codeid'=>'SO_TYP', 'codename_c'=>'测试状态']);

        $basSku1 = factory(OracleBasSKU::class)->make(['customerid' => 'TEST_OW']);
        $basSku2 = factory(OracleBasSKU::class)->make(['customerid' => 'TEST_OW']);
        $basSku3 = factory(OracleBasSKU::class)->make(['customerid' => 'TEST_OW']);
        $basSKU = collect([$basSku1,$basSku2,$basSku3]);
        $this->data['sku'] = [];
        $this->data['sku'][] = factory(Commodity::class)->create(['owner_id'=>$this->data['owner']['id'],'sku'=>$basSku1['sku']]);
        $this->data['sku'][] = factory(Commodity::class)->create(['owner_id'=>$this->data['owner']['id'],'sku'=>$basSku2['sku']]);
        $this->data['sku'][] = factory(Commodity::class)->create(['owner_id'=>$this->data['owner']['id'],'sku'=>$basSku3['sku']]);

        $oracleDOCOrderDetail1 = factory(OracleDOCOrderDetail::class)->make(['orderno'=>$wmsOrderHeader->orderno,'customerid'=>'TEST_OW','sku'=>$basSku1->sku]);
        $oracleDOCOrderDetail2 = factory(OracleDOCOrderDetail::class)->make(['orderno'=>$wmsOrderHeader->orderno,'customerid'=>'TEST_OW','sku'=>$basSku2->sku]);
        $oracleDOCOrderDetail3 = factory(OracleDOCOrderDetail::class)->make(['orderno'=>$wmsOrderHeader->orderno,'customerid'=>'TEST_OW','sku'=>$basSku3->sku]);
        $oracleDOCOrderDetails = collect([$oracleDOCOrderDetail1,$oracleDOCOrderDetail3,$oracleDOCOrderDetail2]);
        $wmsOrderHeader->setRelation('oracleDOCOrderDetails',$oracleDOCOrderDetails);

        $OracleActAllocationDetail1 = factory(OracleActAllocationDetails::class)->make(['orderno'=>$wmsOrderHeader->orderno,'customerid'=>'TEST_OW','sku'=>$basSku1->sku]);
        $OracleActAllocationDetail2 = factory(OracleActAllocationDetails::class)->make(['orderno'=>$wmsOrderHeader->orderno,'customerid'=>'TEST_OW','sku'=>$basSku2->sku]);
        $OracleActAllocationDetail3 = factory(OracleActAllocationDetails::class)->make(['orderno'=>$wmsOrderHeader->orderno,'customerid'=>'TEST_OW','sku'=>$basSku3->sku]);
        $OracleActAllocationDetails = collect([$OracleActAllocationDetail1,$OracleActAllocationDetail2,$OracleActAllocationDetail3]);
        $wmsOrderHeader->setRelation('actAllocationDetails',$OracleActAllocationDetails);

        $wmsOrderHeader->setRelation('orderType',$orderType);
        $wmsOrderHeader->setRelation('oracleBASCode',$code_BasCode);
        $this->data['orderHeader'] = $wmsOrderHeader;

        $this->mock(OracleBasSkuService::class,function($mock)use($basSKU){
            $mock->shouldReceive('get')->andReturn($basSKU);
        });

    }

    /**
     * @test
     */
    public function createOrFindOrderInfo()
    {
        $this->orderService->createOrFindOrderInfo($this->data['orderHeader']);
        $order = Order::query()->where('code',$this->data['orderHeader']['orderno'])->first();
        $this->assertNotNull($order);
        $this->assertEquals($order->code,$this->data['orderHeader']['orderno']);
        $orderPackages  = OrderPackage::query()->where('order_id',$order['id'])->get();
        $orderPackagesCommodities = OrderPackageCommodities::query()->whereIn('order_package_id',data_get($orderPackages,'*.id'))->get();
        $this->assertNotEmpty($orderPackages);
        $this->assertNotEmpty($orderPackagesCommodities);
    }

    public function tearDown(): void
    {
        foreach ($this->data['sku'] as $datum) {
            cache()->forget("owner_code_{$this->data['owner']['code']}_sku_{$datum['sku']}");
        }
        cache()->forget("getLogisticByCode_{$this->data['logistic']}");
        cache()->forget("getOwnerByCode_{$this->data['owner']}");
        cache()->forget("getShopByCodeMap_{$this->data['shop']}");
        cache()->forget("WareHouse_{$this->data['warehouse']}");

        Commodity::query()->whereIn('id',data_get($this->data['sku'],'*.id'))->delete();
        $order = Order::query()->where('code',$this->data['orderHeader']['orderno'])->first();
        $order->delete();
        $this->data['logistic']->delete();
        $this->data['owner']->delete();
        $this->data['shop']->delete();
        $this->data['warehouse']->delete();
        parent::tearDown(); // TODO: Change the autogenerated stub
    }
}
