<?php


namespace Tests\Services\OwnerPriceOperationService;

use App\Commodity;
use App\Owner;
use App\OwnerInStorageRule;
use App\OwnerOutStorageRule;
use App\OwnerPriceOperation;
use App\Services\FeatureService;
use App\Services\OwnerPriceOperationService;
use App\Unit;
use Mockery\Mock;
use Tests\TestCase;

class OwnerPriceOperationServiceTest extends  TestCase
{
    /** @var OwnerPriceOperationService */
    public $service;
    public $data;

    protected function setUp(): void
    {
        parent::setUp();
        $this->service = app(OwnerPriceOperationService::class);

        $this->data["units"] = [];
        $pieces = Unit::query()->where("name","件")->first();
        $box = Unit::query()->where("name","箱")->first();
        $single = Unit::query()->where("name","单")->first();
        if (!$pieces){
            $pieces = factory(Unit::class)->create(["name"=>"件"]);
            $this->data["units"][] = $pieces->toArray();
        }
        if (!$box){
            $box = factory(Unit::class)->create(["name"=>"箱"]);
            $this->data["units"][] = $box->toArray();
        }
        if (!$single){
            $single = factory(Unit::class)->create(["name"=>"单"]);
            $this->data["units"][] = $single->toArray();
        }
        $model1 = factory(OwnerPriceOperation::class)->create([
            "operation_type"=>"入库",   //操作类型
            "strategy"      =>"默认",         //策略
        ]);
        $model2 = factory(OwnerPriceOperation::class)->create([
            "operation_type"=>"入库",   //操作类型
            "strategy"      =>"特征",         //策略
        ]);
        $model3 = factory(OwnerPriceOperation::class)->create([
            "operation_type"=>"出库",   //操作类型
            "strategy"      =>"默认",         //策略
        ]);
        $model4 = factory(OwnerPriceOperation::class)->create([
            "operation_type"=>"出库",   //操作类型
            "strategy"      =>"特征",         //策略
        ]);
        $this->data["models"] = [$model1->toArray(),$model2->toArray(),$model3->toArray(),$model4->toArray()];

        $in1 = factory(OwnerInStorageRule::class)->create([
            "owner_price_operation_id"  => $model1->id, //作业计费ID
            "amount"                    => 5,                   //计量
            "unit_id"                   => $pieces->id,//单位ID
            "unit_price"                => 2.22,               //单价
        ]);
        $in2 = factory(OwnerInStorageRule::class)->create([
            "owner_price_operation_id"  => $model2->id, //作业计费ID
            "amount"                    => 5,                   //计量
            "unit_id"                   => $box->id,//单位ID
            "unit_price"                => 3.22,               //单价
        ]);
        $out1 = factory(OwnerOutStorageRule::class)->create([
            "owner_price_operation_id"          => $model3->id,
            "strategy"                          =>"起步",
            "amount"                            =>6,
            "unit_id"                           => $box->id,
            "unit_price"                        => 2.22,
        ]);
        $out4 = factory(OwnerOutStorageRule::class)->create([
            "owner_price_operation_id"          => $model3->id,
            "strategy"                          => "默认",
            "unit_id"                           => $box->id,
            "unit_price"                        => 3.22,
        ]);
        $out5 = factory(OwnerOutStorageRule::class)->create([
            "owner_price_operation_id"          => $model3->id,
            "strategy"                          =>"特征",
            "unit_id"                           => $box->id,
            "unit_price"                        => 4.22,
        ]);
        $out6 = factory(OwnerOutStorageRule::class)->create([
            "owner_price_operation_id"          => $model4->id,
            "strategy"                          =>"起步",
            "amount"                            => 6,
            "unit_id"                           => $box->id,
            "unit_price"                        => 5.1,
        ]);
        $out7 = factory(OwnerOutStorageRule::class)->create([
            "owner_price_operation_id"          => $model4->id,
            "strategy"                          => "默认",
            "unit_id"                           => $box->id,
            "unit_price"                        => 5.2,
        ]);
        $out8 = factory(OwnerOutStorageRule::class)->create([
            "owner_price_operation_id"          => $model4->id,
            "strategy"                          =>"特征",
            "unit_id"                           => $box->id,
            "unit_price"                        => 5.3,
        ]);
        $this->data["in"] = [$in1->toArray(),$in2->toArray()];
        $this->data["out"] = [$out1->toArray(),$out4->toArray(),$out5->toArray(),$out6->toArray(),$out7->toArray(),$out8->toArray()];
        $owner = factory(Owner::class)->create([
            "user_owner_group_id" => 1,
        ]);
        $model1->ownerPriceOperationOwners()->sync([$owner->id]);
        $model2->ownerPriceOperationOwners()->sync([$owner->id]);
        $model3->ownerPriceOperationOwners()->sync([$owner->id]);
        $model4->ownerPriceOperationOwners()->sync([$owner->id]);
        $this->data["owners"] = [$owner->toArray()];
        $this->data["commodities"] = [];
        $commodity = factory(Commodity::class)->create([
            'sku' => md5(date('Ymd').\Illuminate\Support\Str::random(3)),
            'owner_id' => $owner->id,
            "pack_spec" => 3
        ]);
        $this->data["commodities"][] = $commodity->toArray();
    }

    /**
     * @group customer
     */
    public function testMatchRule()
    {
        $this->partialMock(FeatureService::class,function ($mock){
            /** @var Mock $mock */
            $mock->shouldReceive("matchFeature")->andReturn(true);
        });
        $result = $this->service->matchRule(["packages"=>[["commodity"=>"测试","amount"=>55,"sku"=>$this->data["commodities"][0]["sku"]]]],[],$this->data["owners"][0]["id"],"入库");
        $this->assertEquals(12.88,$result);
        $result = $this->service->matchRule(["packages"=>[["commodity"=>"测试","amount"=>57,"sku"=>$this->data["commodities"][0]["sku"]]]],[],$this->data["owners"][0]["id"],"出库");
        $this->assertEquals(99.5,$result);
    }
    /**
     * @group customer
     */
    public function testMatchRule1()
    {
        $result = $this->service->matchRule(["packages"=>[["commodity"=>"测试","amount"=>56,"sku"=>$this->data["commodities"][0]["sku"]]]],[],$this->data["owners"][0]["id"],"入库");
        $this->assertEquals(26.64,$result);
        $result = $this->service->matchRule(["packages"=>[["commodity"=>"测试","amount"=>58,"sku"=>$this->data["commodities"][0]["sku"]]]],[],$this->data["owners"][0]["id"],"出库");
        $this->assertEquals(58.4,$result);
    }

    public function tearDown(): void
    {
        Unit::destroy(array_column($this->data["units"],"id"));
        OwnerPriceOperation::destroy(array_column($this->data["models"],"id"));
        foreach ($this->data["models"] as $d){
            $model = new OwnerPriceOperation();
            $model->id = $d["id"];
            $model->ownerPriceOperationOwners()->sync([]);
        }
        OwnerInStorageRule::destroy(array_column($this->data["in"],"id"));
        OwnerOutStorageRule::destroy(array_column($this->data["out"],"id"));
        Owner::destroy(array_column($this->data["owners"],"id"));
        Commodity::destroy(array_column($this->data["commodities"],"id"));
        parent::tearDown();
    }
}