<?php

namespace App\Services\Business;

use App\Models\Business\WashOrder;
use BlueCity\Core\Service\Service;
use Illuminate\Support\Facades\DB;
use App\Http\Models\Api\WarehouseManage\Stocktake;
use App\Http\Models\Api\OutinRecord;

class WashMyWarehouseService extends Service
{
    public static $instance;
    public $modelMain = null;
    public $mainValidator = null;

    public function __construct()
    {
        // $this->mainValidator = new WashMyWarehouseValidator();
    }

    /**
     * @return mixed
     */
    public static function getInstance()
    {
        if (is_null(static::$instance)) {
            static::$instance = new static;
        }
        return static::$instance;
    }

    /**
     * 转库存
     * @authors ldj
     * @email  909490343@qq.com
     * @date   2024-06-25
     * @param  [type]           $id     [description]
     * @param  string           $fields [description]
     * @param  integer          $shopID [description]
     * @return [type]                   [description]
     */
    public static function unitConversion($user_info, $request)
    {
        $find_goods = DB::table('warehouse_goods')
            ->leftJoin('goods', 'goo_id', '=', 'wago_goo_id')
            ->where('wago_id', $request['wago_id'])
            ->first();//要转换的商品
        if ($find_goods->goo_level == 1) {
            $main_goo_id = $find_goods->goo_id;
            $main_goods = $find_goods;//主商品
            $get_goods = DB::table('goods')
                ->where('goo_fid', $find_goods->goo_id)
                ->where('goo_level', 2)
                ->first();//副商品
            $by_goods =  DB::table('warehouse_goods')
                ->where('wago_ware_id', $find_goods->wago_ware_id)
                ->where('wago_goo_id', $get_goods->goo_id)
                ->first();//副商品仓库商品
            $wafg_wafr_id = DB::table('warehouse_freight')
                ->where('wafr_ware_id', $main_goods->wago_ware_id)
                ->where('wafr_shop_id', $user_info->adm_shop_id)
                ->value('wafr_id');
            if (!$by_goods) {
                $add_wago_data['wago_ware_id'] = $main_goods->wago_ware_id;
                $add_wago_data['wago_goo_id'] = $get_goods->goo_id;
                $add_wago_data['wago_goo_price'] = $get_goods->goo_purchase_price/100;
                $wago_id = DB::table('warehouse_goods')->insertGetId($add_wago_data);
                $add_wafg_data['wafg_wafr_id'] = $wafg_wafr_id;
                $add_wafg_data['wafg_wago_id'] = $wago_id;
                $add_wafg_data['wafg_ware_id'] = $main_goods->wago_ware_id;
                $add_wafg_data['wafg_goo_id'] = $get_goods->goo_id;
                $add_wafg_res = DB::table('warehouse_freight_goods')->insertGetId($add_wafg_data);
            }
            $by_goods = DB::table('warehouse_goods')
                ->leftJoin('goods', 'goo_id', '=', 'wago_goo_id')
                ->where('wago_ware_id', $find_goods->wago_ware_id)
                ->where('wago_goo_id', $get_goods->goo_id)
                ->first();//要转换的商品
            $fu_goo_id = $get_goods->goo_id;
        } elseif($find_goods->goo_level == 2) {//
            $by_goods  = $find_goods;//副商品
            $get_goods = DB::table('goods')
                ->where('goo_id', $find_goods->goo_fid)
                ->where('goo_level', 1)
                ->first();//主商品
            $main_goods =  DB::table('warehouse_goods')
                ->where('wago_ware_id', $find_goods->wago_ware_id)
                ->where('wago_goo_id', $get_goods->goo_id)
                ->first();//主商品仓库商品
            $wafg_wafr_id = DB::table('warehouse_freight')
                ->where('wafr_ware_id', $by_goods->wago_ware_id)
                ->where('wafr_shop_id', $user_info->adm_shop_id)
                ->value('wafr_id');
            if (!$main_goods) {
                $add_wago_data['wago_ware_id'] = $by_goods->wago_ware_id;
                $add_wago_data['wago_goo_id'] = $get_goods->goo_id;
                $add_wago_data['wago_goo_price'] = $get_goods->goo_purchase_price/100;
                $wago_id = DB::table('warehouse_goods')->insertGetId($add_wago_data);
                $add_wafg_data['wafg_wafr_id'] = $wafg_wafr_id;
                $add_wafg_data['wafg_wago_id'] = $wago_id;
                $add_wafg_data['wafg_ware_id'] = $by_goods->wago_ware_id;
                $add_wafg_data['wafg_goo_id'] = $get_goods->goo_id;
                $add_wafg_res = DB::table('warehouse_freight_goods')->insertGetId($add_wafg_data);
            }
            $main_goods = DB::table('warehouse_goods')
                ->leftJoin('goods', 'goo_id', '=', 'wago_goo_id')
                ->where('wago_ware_id', $find_goods->wago_ware_id)
                ->where('wago_goo_id', $get_goods->goo_id)
                ->first();//要转换的商品
        } else {
            return ['code'=>500,'msg'=>'此商品不支持转换','data'=>''];
        }
        if (!is_numeric($request['num']) || $request['num'] < 1) {
            return ['code'=>500,'msg'=>'输入数量错误','data'=>''];
        }
        if ($request['change_type'] == 1) {//卷转换米
            if ($main_goods->wago_stock_number < $request['num']) {
                return ['code'=>500,'msg'=>'主商品库存不足','data'=>''];
            }
            if ($main_goods->goo_unit_conversion > 1) {
                $stoc_type = 1;
            } elseif ($main_goods->goo_unit_conversion == 1) {
                $stoc_type = 3;
            } else {
                $stoc_type = 2;
            }
            //卷减少库存 米增加库存
            $stgo_data[0]['stgo_goo_id'] = $main_goods->goo_id; //商品id
            $stgo_data[0]['stgo_stock_number'] = $main_goods->wago_stock_number; //良品库存数量
            $stgo_data[0]['stgo_stocktake_number'] = -$request['num']; //良品盘点数量
            // 仓位商品表增加库存
            $wafg_stock_number = DB::table('warehouse_freight_goods')
                ->where('wafg_ware_id', $find_goods->wago_ware_id)
                ->where('wafg_class', 1)
                ->where('wafg_wago_id', $main_goods->wago_id)
                // ->where('wafg_wafr_id', $value['stgo_wafr_id'])
                ->decrement('wafg_stock_number', $request['num']);

            // 更改仓库商品表库存数量
            $wago_edit_data['wago_stock_number'] = $main_goods->wago_stock_number - $request['num'];
            $wago_edit_data['wago_goo_amount'] = $wago_edit_data['wago_stock_number'] * $main_goods->wago_goo_price;
            $wago_edit_data['wago_freight_stock_number'] = $main_goods->wago_freight_stock_number - $request['num'];
            $wago_edit_data['wago_update_time'] = date('Y-m-d H:i:s');
            // 仓库商品表优先数量增加
            $wago_stock_number = DB::table('warehouse_goods')
                ->where('wago_ware_id', $find_goods->wago_ware_id)
                ->where('wago_class', 1)
                ->where('wago_id', $main_goods->wago_id)
                ->update($wago_edit_data);
            unset($wago_edit_data);

            $stgo_data[1]['stgo_goo_id'] = $by_goods->goo_id; //商品id
            $stgo_data[1]['stgo_stock_number'] = $by_goods->wago_stock_number; //良品库存数量
            $stgo_data[1]['stgo_stocktake_number'] = +$request['num']*$main_goods->goo_unit_conversion; //良品盘点数量
            // 仓位商品表增加库存
            $wafg_stock_number = DB::table('warehouse_freight_goods')
                ->where('wafg_ware_id', $find_goods->wago_ware_id)
                ->where('wafg_class', 1)
                ->where('wafg_wago_id', $by_goods->wago_id)
                // ->where('wafg_wafr_id', $value['stgo_wafr_id'])
                ->increment('wafg_stock_number', ($request['num']*$main_goods->goo_unit_conversion));

            // 更改仓库商品表库存数量
            $wago_edit_data['wago_stock_number'] = $by_goods->wago_stock_number + $request['num']*$main_goods->goo_unit_conversion;
            $wago_edit_data['wago_freight_stock_number'] = $by_goods->wago_freight_stock_number + $request['num']*$main_goods->goo_unit_conversion;
            $wago_edit_data['wago_goo_amount'] = $wago_edit_data['wago_stock_number'] * $by_goods->wago_goo_price;
            $wago_edit_data['wago_update_time'] = date('Y-m-d H:i:s');
            // 仓库商品表优先数量增加
            $wago_stock_number = DB::table('warehouse_goods')
                ->where('wago_ware_id', $find_goods->wago_ware_id)
                ->where('wago_class', 1)
                ->where('wago_id', $by_goods->wago_id)
                ->update($wago_edit_data);
            unset($wago_edit_data);
            $stocktake_number = -$request['num'] + ($request['num']*$main_goods->goo_unit_conversion); //良品盘点数量
        } else {//米转卷
            if ($by_goods->wago_stock_number < ($request['num']*$main_goods->goo_unit_conversion)) {
                return ['code'=>500,'msg'=>'副商品库存不足','data'=>''];
            }
            if ($main_goods->goo_unit_conversion > 1) {
                $stoc_type = 2;
            } elseif ($main_goods->goo_unit_conversion == 1) {
                $stoc_type = 3;
            } else {
                $stoc_type = 1;
            }
            //米减少库存 卷增加库存
            $stgo_data[0]['stgo_goo_id'] = $main_goods->goo_id; //商品id
            $stgo_data[0]['stgo_stock_number'] = $main_goods->wago_stock_number; //良品库存数量
            $stgo_data[0]['stgo_stocktake_number'] = $request['num']; //良品盘点数量
            // 仓位商品表增加库存
            $wafg_stock_number = DB::table('warehouse_freight_goods')
                ->where('wafg_ware_id', $find_goods->wago_ware_id)
                ->where('wafg_class', 1)
                ->where('wafg_wago_id', $main_goods->wago_id)
                // ->where('wafg_wafr_id', $value['stgo_wafr_id'])
                ->increment('wafg_stock_number', $request['num']);

            // 更改仓库商品表库存数量
            $wago_edit_data['wago_stock_number'] = $main_goods->wago_stock_number + $request['num'];
            $wago_edit_data['wago_freight_stock_number'] = $main_goods->wago_freight_stock_number + $request['num'];
            $wago_edit_data['wago_goo_amount'] = $wago_edit_data['wago_stock_number'] * $main_goods->wago_goo_price;
            $wago_edit_data['wago_update_time'] = date('Y-m-d H:i:s');
            // 仓库商品表优先数量增加
            $wago_stock_number = DB::table('warehouse_goods')
                ->where('wago_ware_id', $find_goods->wago_ware_id)
                ->where('wago_class', 1)
                ->where('wago_id', $main_goods->wago_id)
                ->update($wago_edit_data);
            unset($wago_edit_data);
            $stgo_data[1]['stgo_goo_id'] = $by_goods->goo_id; //商品id
            $stgo_data[1]['stgo_stock_number'] = $by_goods->wago_stock_number; //良品库存数量
            $stgo_data[1]['stgo_stocktake_number'] = -($request['num']*$main_goods->goo_unit_conversion); //良品盘点数量
            // 仓位商品表增加库存
            $wafg_stock_number = DB::table('warehouse_freight_goods')
                ->where('wafg_ware_id', $find_goods->wago_ware_id)
                ->where('wafg_class', 1)
                ->where('wafg_wago_id', $by_goods->wago_id)
                // ->where('wafg_wafr_id', $value['stgo_wafr_id'])
                ->decrement('wafg_stock_number', $request['num']*$main_goods->goo_unit_conversion);

            // 更改仓库商品表库存数量
            $wago_edit_data['wago_stock_number'] = $by_goods->wago_stock_number - $request['num']*$main_goods->goo_unit_conversion;
            $wago_edit_data['wago_freight_stock_number'] = $by_goods->wago_freight_stock_number - $request['num']*$main_goods->goo_unit_conversion;
            $wago_edit_data['wago_goo_amount'] = $wago_edit_data['wago_stock_number'] * $by_goods->wago_goo_price;
            $wago_edit_data['wago_update_time'] = date('Y-m-d H:i:s');
            // 仓库商品表优先数量增加
            $wago_stock_number = DB::table('warehouse_goods')
                ->where('wago_ware_id', $find_goods->wago_ware_id)
                ->where('wago_class', 1)
                ->where('wago_id', $by_goods->wago_id)
                ->update($wago_edit_data);
            unset($wago_edit_data);
            $stocktake_number = $request['num'] - ($request['num']*$main_goods->goo_unit_conversion); //良品盘点数量
        }
        $find_waon_data = DB::table('warehouse_onhand')
            ->where('waon_ware_id', $find_goods->wago_ware_id)
            ->where('waon_class', 1)
            ->first();
        $update_waon['waon_all_amount'] = $find_waon_data->waon_all_amount + $stocktake_number;
        $update_waon['waon_stock_fine_amount'] = $find_waon_data->waon_stock_fine_amount + $stocktake_number;
        $updare_waon_res = DB::table('warehouse_onhand')
            ->where('waon_id', $find_waon_data->waon_id)
            ->update($update_waon);
        // 新增盘库单
        // 1 新增一个盘库单数据
        $stoc_data['stoc_cid'] = $user_info->adm_cid;
        $stoc_data['stoc_shop_id'] = $user_info->adm_shop_id;
        $stoc_data['stoc_superior_shop_id'] = $user_info->shop_superior_id;
        $stoc_data['stoc_adm_id'] = $user_info->adm_id;
        $stoc_data['stoc_storage_number'] = 'P' . truncateFill($user_info->adm_shop_id, 2) . date('mdHis') . truncateFill($user_info->adm_id, 2) . rand(10000, 99999);
        $stoc_data['stoc_type'] = $stoc_type;//// 类型：1盘盈2盘亏3盘平
        $stoc_data['stoc_differ_number'] = abs($stocktake_number);
        
        $stoc_data['stoc_state'] = 3; //状态1保存/待提交2提交/待审核3通过4驳回
        $stoc_data['stoc_remark'] = isset($request['stoc_remark']) ? $request['stoc_remark'] : '';
        $stoc_data['stoc_ware_id'] = $main_goods->wago_ware_id;
        $stoc_data['stoc_make_time'] = date('Y-m-d H:i:s');
        $stoc_data['stoc_waon_class'] = 1;
        $stoc_data['stoc_manner'] = 1;

        // 新增盘库单
        $stoc_res =  DB::table('stocktake')->insertGetId($stoc_data);
        $stoc_data['stoc_id'] = $stoc_res;
        $diff_ware_amount = 0; //盘库差异数量

        $diff_stock_amount = 0; //盘库良品差异数量
        $diff_priority_amount = 0; //盘库优先差异数量

        $diff_stock_goo_number = []; //盘库单的商品良品差异数量
        $diff_priority_goo_number = []; //盘库单的商品优先差异数量
        // 2. 新增盘点商品数据
        foreach ($stgo_data as $key => $value) {
            $stgo_data[$key]['stgo_stoc_id'] = $stoc_res;
            $stgo_res =  DB::table('stocktake_goods')->insert($stgo_data[$key]);
            if ($value['stgo_stocktake_number'] > 0) {
                $intype = 2; //出入库类型：1出库2入库
            } else {
                $intype = 1;
            }
            // 良品库存盘点
            if ($value['stgo_stocktake_number'] != 0) {
                $diff_stock_amount = $diff_stock_amount + $value['stgo_stocktake_number'];

                // 仓库流水记录使用数组
                if (isset($diff_stock_goo_number[$value['stgo_goo_id']])) {
                    $diff_stock_goo_number[$value['stgo_goo_id']] += $value['stgo_stocktake_number'];
                } else {
                    $diff_stock_goo_number[$value['stgo_goo_id']] = $value['stgo_stocktake_number'];
                }
            }
            // 仓位入库记录
            $outin_recore_res = Stocktake::junkaddition(
                $user_info,
                $stoc_data['stoc_ware_id'], //仓库id
                $stoc_data['stoc_waon_class'], //仓库类型
                $wafg_wafr_id, //仓位id
                7, //盘库
                $stoc_res, //原始单id
                $stoc_data['stoc_storage_number'], //原始单单号
                $stgo_res, //关联商品表主键id-盘库单商品表主键id
                $value['stgo_goo_id'], //商品id
                $intype, //出入库类型：1出库2入库
                $value['stgo_stocktake_number'], //商品数量
                1 //出库类型1良品2优先3待检测
            );
        }

        // 良品库存盘点
        if (!empty($diff_stock_goo_number)) {
            $out_goo_id = []; //出库
            $out_goo_number = []; //出库
            $out_goo_inventory = []; //出库

            $diff_stock_amount_out = 0; //盘库良品差异数量
            $diff_stock_amount_in = 0; //盘库良品差异数量

            $in_goo_id = []; //入库
            $in_goo_number = []; //入库
            $in_goo_inventory = []; //入库
            foreach ($diff_stock_goo_number as $key => $value) {
                if ($value > 0) {
                    $diff_stock_amount_in += abs($value);
                    $in_goo_number[$key] = abs($value);
                    $in_goo_id[$key] = $key;
                    $in_goo_inventory[$key] = 1;
                } else if ($value < 0) {
                    $diff_stock_amount_out += abs($value);
                    $out_goo_number[$key] = abs($value);
                    $out_goo_id[$key] = $key;
                    $out_goo_inventory[$key] = 1;
                }
            }
            if (!empty($out_goo_number)) {
                $outware = $stoc_data['stoc_ware_id']; //仓库id
                $inware = 0; //入库仓库id
                $intype = 1; //出入库类型：1出库2入库
                $outtype = 2; //操作类型：1锁定库存2出库3入库4调货5发货

                // 3.生成出出库记录
                $oure_data = OutinRecord::addition(
                    $user_info, //用户信息
                    $stoc_data['stoc_id'], //原始单的关联id
                    $stoc_data['stoc_storage_number'], //原始单的关联单号
                    8, //原始单的关联类型1.订单2.调拨单3.采购单4.销售单5.旧货回收6.退货入库7.售后8盘库单
                    5, //买家类型：1.会员零售2.客户单位3.速电派单4.第三方派单5盘库单
                    0, //选择的客户id,会员id/单位id
                    $stoc_data['stoc_storage_number'], //原始单号
                    $inware, //入库仓库id
                    $outware, //出库仓库id
                    $diff_stock_amount_out, //出库的商品总量
                    15, //类型1.入库单 2.出库单 3.调货单 4.旧货回收单 5.退换回收单 6.订单出库 7.部分入库 8.部分出库 9.发货单15盘库单
                    $outtype, //操作类型：1锁定库存2出库3入库4调货5发货
                    $find_waon_data->waon_stock_fine_amount, //良品总库存
                    $find_waon_data->waon_lock_fine_amount, //良品锁定数量
                    $find_waon_data->waon_stock_priority_amount, //优先总库存
                    $find_waon_data->waon_lock_priority_amount, //优先锁定数量
                    $find_waon_data->waon_stock_unchecked_amount, //待检测总库存
                    $intype, //出入库类型：1出库，2入库
                    $stoc_data['stoc_waon_class'], //[仓库类别]
                    $out_goo_id, //数组，商品id
                    $out_goo_number, //数组，商品数量
                    $out_goo_inventory //数组，出库类型1良品2优先3待检测
                );
                if (!$oure_data) {
                    return ['code' => 500, 'msg' => 'error', 'data' => '出入库记录保存失败！1'];
                }
            }

            if (!empty($in_goo_number)) {
                $intype = 2; //出入库类型：1出库2入库
                $outtype = 3; //操作类型：1锁定库存2出库3入库4调货5发货
                $outware = 0; //出库仓库id
                $inware = $stoc_data['stoc_ware_id']; //仓库id
                // 3.生成出出库记录
                $oure_data = OutinRecord::addition(
                    $user_info, //用户信息
                    $stoc_data['stoc_id'], //原始单的关联id
                    $stoc_data['stoc_storage_number'], //原始单的关联单号
                    8, //原始单的关联类型1.订单2.调拨单3.采购单4.销售单5.旧货回收6.退货入库7.售后8盘库单
                    5, //买家类型：1.会员零售2.客户单位3.速电派单4.第三方派单5盘库单
                    0, //选择的客户id,会员id/单位id
                    $stoc_data['stoc_storage_number'], //原始单号
                    $inware, //入库仓库id
                    $outware, //出库仓库id
                    $diff_stock_amount_in, //出库的商品总量
                    15, //类型1.入库单 2.出库单 3.调货单 4.旧货回收单 5.退换回收单 6.订单出库 7.部分入库 8.部分出库 9.发货单15盘库单
                    $outtype, //操作类型：1锁定库存2出库3入库4调货5发货
                    $find_waon_data->waon_stock_fine_amount, //良品总库存
                    $find_waon_data->waon_lock_fine_amount, //良品锁定数量
                    $find_waon_data->waon_stock_priority_amount, //优先总库存
                    $find_waon_data->waon_lock_priority_amount, //优先锁定数量
                    $find_waon_data->waon_stock_unchecked_amount, //待检测总库存
                    $intype, //出入库类型：1出库，2入库
                    $stoc_data['stoc_waon_class'], //[仓库类别]
                    $in_goo_id, //数组，商品id
                    $in_goo_number, //数组，商品数量
                    $in_goo_inventory //数组，出库类型1良品2优先3待检测
                );
                if (!$oure_data) {
                    return ['code' => 500, 'msg' => 'error', 'data' => '出入库记录保存失败！2'];
                }
            }

            unset($out_goo_id);
            unset($out_goo_number);
            unset($out_goo_inventory);
            unset($in_goo_id);
            unset($in_goo_number);
            unset($in_goo_inventory);
        }
        
        $old_goods_data[]['goo_id'] = $main_goods->goo_id;
        $new_goods_data[]['goo_id'] = $by_goods->goo_id;
        $post_data['ware_id'] = $inware;
        $post_data['new_goods_data'] = $new_goods_data;
        $res = WashOrderBasicService::addGoodPlan($user_info, $post_data);

        $post_data1['ware_id'] = $inware;
        $post_data1['new_goods_data'] = $old_goods_data;
        $res = WashOrderBasicService::addGoodPlan($user_info, $post_data1);
        return ['code'=>200,'msg'=>'转库存成功','data'=>''];
    }
}
