Explorar el Código

Merge branch 'master' into zengjun

# Conflicts:
#	app/Http/Controllers/TestController.php
ajun hace 5 años
padre
commit
ed1e9f6004
Se han modificado 63 ficheros con 949 adiciones y 289 borrados
  1. 6 1
      app/Console/Commands/CreateOwnerBillReport.php
  2. 3 3
      app/Events/AddOrUpdateOrderIssues.php
  3. 4 3
      app/Http/Controllers/CommodityController.php
  4. 3 2
      app/Http/Controllers/CustomerController.php
  5. 1 1
      app/Http/Controllers/InventoryAccountController.php
  6. 2 0
      app/Http/Controllers/LogisticController.php
  7. 8 1
      app/Http/Controllers/PackageLogisticController.php
  8. 64 6
      app/Http/Controllers/PriceModelController.php
  9. 1 0
      app/Http/Controllers/ProcurementController.php
  10. 15 56
      app/Http/Controllers/TestController.php
  11. 5 5
      app/Http/Controllers/UserController.php
  12. 1 1
      app/Http/Controllers/WaybillController.php
  13. 4 0
      app/Http/Controllers/api/thirdPart/haiq/LightController.php
  14. 40 11
      app/Http/Controllers/api/thirdPart/weixin/ProcurementController.php
  15. 8 0
      app/Jobs/LogisticZopSync.php
  16. 2 2
      app/Jobs/ProcurementConfirmInform.php
  17. 39 16
      app/Jobs/ResetInstantBill.php
  18. 9 11
      app/Listeners/AddOrUpdateOrderIssuesListener.php
  19. 1 1
      app/Logistic.php
  20. 17 1
      app/Owner.php
  21. 2 1
      app/OwnerBillReport.php
  22. 2 0
      app/OwnerFeeDetail.php
  23. 1 1
      app/OwnerFeeDetailLogistic.php
  24. 5 1
      app/OwnerPriceDirectLogistic.php
  25. 5 0
      app/OwnerPriceExpress.php
  26. 5 0
      app/OwnerPriceLogistic.php
  27. 5 0
      app/OwnerPriceOperation.php
  28. 16 0
      app/OwnerPriceSystem.php
  29. 5 0
      app/OwnerStoragePriceModel.php
  30. 40 26
      app/Procurement.php
  31. 9 7
      app/Services/InventoryAccountService.php
  32. 4 3
      app/Services/LogService.php
  33. 8 0
      app/Services/LogisticSFService.php
  34. 42 22
      app/Services/OrderService.php
  35. 5 4
      app/Services/OwnerPriceDirectLogisticService.php
  36. 6 5
      app/Services/OwnerPriceExpressService.php
  37. 8 6
      app/Services/OwnerPriceLogisticService.php
  38. 20 7
      app/Services/OwnerPriceOperationService.php
  39. 6 5
      app/Services/RejectedBillService.php
  40. 4 3
      app/Services/StoreService.php
  41. 4 3
      app/Services/WaybillService.php
  42. 13 6
      app/Services/common/QueryService.php
  43. 1 1
      config/api.php
  44. 76 0
      database/migrations/2021_04_16_151135_create_owner_price_systems_table.php
  45. 9 4
      resources/js/queryForm/header.js
  46. 76 10
      resources/views/customer/project/create.blade.php
  47. 3 2
      resources/views/customer/project/index.blade.php
  48. 6 0
      resources/views/customer/project/part/_directLogistic.blade.php
  49. 7 1
      resources/views/customer/project/part/_express.blade.php
  50. 7 1
      resources/views/customer/project/part/_logistic.blade.php
  51. 6 0
      resources/views/customer/project/part/_operation.blade.php
  52. 6 0
      resources/views/customer/project/part/_storage.blade.php
  53. 13 0
      resources/views/customer/project/part/_system.blade.php
  54. 37 2
      resources/views/customer/project/part/_three.blade.php
  55. 6 0
      resources/views/maintenance/logistic/create.blade.php
  56. 6 0
      resources/views/maintenance/logistic/edit.blade.php
  57. 2 2
      resources/views/maintenance/logistic/index.blade.php
  58. 7 5
      resources/views/package/logistic/index.blade.php
  59. 32 3
      resources/views/rejected/create.blade.php
  60. 193 36
      resources/views/test.blade.php
  61. 2 0
      routes/web.php
  62. 5 0
      tests/Feature/LogisticZopSyncTest.php
  63. 1 1
      tests/Services/LogisticQiaoSFService/LogisticQiaoSFServiceTest.php

+ 6 - 1
app/Console/Commands/CreateOwnerBillReport.php

@@ -3,6 +3,7 @@
 namespace App\Console\Commands;
 
 use App\OwnerAreaReport;
+use App\OwnerPriceSystem;
 use App\Services\LogService;
 use Illuminate\Console\Command;
 use Illuminate\Support\Facades\DB;
@@ -62,19 +63,23 @@ class CreateOwnerBillReport extends Command
                     ->calculationAmount($area->ownerStoragePriceModel,$area->accounting_area,$area->owner_id,$area->counting_month);
             }
         }
-
+        foreach (OwnerPriceSystem::query()->select("owner_id","usage_fee")->whereNull("operation")->orWhere("operation","")->get() as $system){
+            $systemFee[$system->owner_id] = $system->usage_fee;
+        }
         $chunks = array_chunk($billDetails,50);
         foreach ($chunks as $bills){
             $date = date('Y-m-d H:i:s');
             $createOwnerBillReport = [];
             foreach ($bills as $bill){
                 $key = $bill->owner_id."_".$year."-".$lastMonth;
+                $otherFee = $systemFee[$bill->owner_id] ?? null;
                 $createOwnerBillReport[] = [
                     "owner_id"          => $bill->owner_id,       //项目ID
                     "counting_month"    => $year."-".$lastMonth."-01", //结算月
                     "work_fee"          => $bill->work_fee,
                     "logistic_fee"      => $bill->logistic_fee,
                     "storage_fee"       => $map[$key] ?? 0,
+                    "other_fee"         => $otherFee,
                     "created_at"        => $date,
                 ];
             }

+ 3 - 3
app/Events/AddOrUpdateOrderIssues.php

@@ -15,11 +15,11 @@ class AddOrUpdateOrderIssues
 
     /**
      * AddOrderIssues constructor.
-     * @param $logisticNumbers
+     * @param $order_ids
      */
-    public function __construct($logisticNumbers)
+    public function __construct($order_ids)
     {
-        $this->order_ids = $logisticNumbers;
+        $this->order_ids = $order_ids;
     }
 
 

+ 4 - 3
app/Http/Controllers/CommodityController.php

@@ -172,14 +172,15 @@ class CommodityController extends Controller
     public function apiGetCommodityByBarcode(Request $request)
     {
         $barcode=$request->input('barcode');
-        $name = '';
+//        $name = '';
+        $commodity = '';
         if($barcode){
             $commodity=Commodity::query()->whereHas('barcodes', function (Builder $query)use($barcode){
                 $query->where('code',$barcode);
             })->first();
-            if($commodity&&$commodity['name']) $name=$commodity['name'];
+//            if($commodity&&$commodity['name']) $name=$commodity['name'];
         }
-        return ['success'=>'true','name'=>$name];
+        return ['success'=>'true','commodity'=>$commodity];
     }
 
     public function syncWMS(Request $request){

+ 3 - 2
app/Http/Controllers/CustomerController.php

@@ -97,7 +97,7 @@ class CustomerController extends Controller
         /** @var OwnerService $service */
         $service = app('OwnerService');
         $owners = $service->paginate(request()->input(),['customer',"userOwnerGroup","userWorkGroup",
-            "ownerStoragePriceModels","storageAudit","operationAudit","expressAudit","logisticAudit","directLogisticAudit"]);
+            "ownerStoragePriceModels","storageAudit","operationAudit","expressAudit","logisticAudit","directLogisticAudit","systemAudit"]);
         $models = app('OwnerService')->getIntersectPermitting();
         $customers = app('CustomerService')->getSelection();
         $ownerGroups = app('UserOwnerGroupService')->getSelection();
@@ -205,13 +205,14 @@ class CustomerController extends Controller
         if(!Gate::allows('项目管理-项目-编辑')){ return redirect('denied');  }
         /** @var Owner $owner */
         $owner = app('OwnerService')->find($id);
-        $owner->loadCount(["ownerStoragePriceModels","ownerPriceOperations","ownerPriceExpresses","ownerPriceLogistics","ownerPriceDirectLogistics"]);
+        $owner->loadCount(["ownerStoragePriceModels","ownerPriceOperations","ownerPriceExpresses","ownerPriceLogistics","ownerPriceDirectLogistics","ownerPriceSystem"]);
         $isExist = false;
         /** @var \stdClass $owner */
         if($owner->owner_storage_price_models_count ||
             $owner->owner_price_operations_count ||
             $owner->owner_price_expresses_count ||
             $owner->owner_price_logistics_count ||
+            $owner->owner_price_system_count ||
             $owner->owner_price_direct_logistics_count) $isExist = true;
         $customers = app('CustomerService')->getSelection();
         $ownerGroups = app('UserOwnerGroupService')->getSelection();

+ 1 - 1
app/Http/Controllers/InventoryAccountController.php

@@ -393,7 +393,7 @@ class InventoryAccountController extends Controller
         }
         $marks = [];
         foreach ($checkData as $inventoryMission) {
-            array_push($marks, $inventoryMission['mark']);
+            if (isset($inventoryMission['mark']))array_push($marks,$inventoryMission['mark']);
         }
         if (in_array('确认差异', $marks) || in_array('跳过', $marks) || in_array('无差异', $marks) || in_array('已复盘无差异', $marks)) return ['success' => false, 'data' => '传入勾选盘点记录存在不可操作项!'];
         /** @var InventoryAccountService $inventoryService */

+ 2 - 0
app/Http/Controllers/LogisticController.php

@@ -45,6 +45,7 @@ class LogisticController extends Controller
     {
         if(!Gate::allows('物流公司-录入')){ return redirect(url('/'));  }
         $this->validatorCreate($request->all())->validate();
+        $request->offsetSet("is_bunched",$request->input("is_bunched") ? 'Y' : 'N');
         $logistic=new Logistic($request->all());
         $logistic->save();
 
@@ -96,6 +97,7 @@ class LogisticController extends Controller
     {
         if(!Gate::allows('物流公司-编辑')){ return redirect(url('/'));  }
         $this->validatorUpdate($request->all(),$logistic->id)->validate();
+        $request->offsetSet("is_bunched",$request->input("is_bunched") ? 'Y' : 'N');
         $logistic->fill($request->all());
         $logistic->update();
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);

+ 8 - 1
app/Http/Controllers/PackageLogisticController.php

@@ -37,6 +37,13 @@ class PackageLogisticController extends Controller
 
     public function update(Request $request)
     {
-        OrderPackage::query()->where('id', $request['id'])->update($request->only('exception_type'));
+        $data = [];
+        if ('无' == $request->input('exception_type')) {
+            $data['exception_type'] = $request->input('exception_type');
+            $data['exception'] = "否";
+        } else{
+            $data['exception_type'] = $request->input('exception_type');
+        }
+        OrderPackage::query()->where('id', $request['id'])->update($data);
     }
 }

+ 64 - 6
app/Http/Controllers/PriceModelController.php

@@ -15,9 +15,11 @@ use App\OwnerPriceLogistic;
 use App\OwnerPriceLogisticDetail;
 use App\OwnerPriceOperation;
 use App\OwnerPriceOperationItem;
+use App\OwnerPriceSystem;
 use App\OwnerStoragePriceModel;
 use App\Services\common\BatchUpdateService;
 use App\Services\common\ExportService;
+use App\Services\common\QueryService;
 use App\Services\LogService;
 use App\Services\OwnerPriceOperationItemService;
 use App\Services\OwnerPriceOperationService;
@@ -1133,6 +1135,7 @@ class PriceModelController extends Controller
             "unit_id"           => request("unit_id"),
             "time_unit_id"      => request("time_unit_id"),
             "amount_interval"   => request("amount_interval") ?? null,
+            "tax_rate_id"       => request("tax_rate_id") ?? null,
         ];
         if (request("id")){
             $model = app('OwnerStoragePriceModelService')->find(request("id"));
@@ -1150,7 +1153,7 @@ class PriceModelController extends Controller
 
     public function apiStoreOperation()
     {
-        $this->gate("项目管理-项目-录入");
+        $this->gate("计费模型-仓储-录入");
         $params = request()->input();
         $params["owner_id"] = [$params["owner_id"]];
         $errors = $this->operationValidator($params,request("id"))->errors();
@@ -1170,6 +1173,7 @@ class PriceModelController extends Controller
             "discount_count"    => implode(",",request("discount_count")),
             "total_price"       => request("total_price"),
             "total_discount_price"=> implode(",",request("total_discount_price")),
+            "tax_rate_id"       => request("tax_rate_id") ?? null,
         ];
         if (request("id")){
             $model = app('OwnerPriceOperationService')->find(request("id"),["items"]);
@@ -1232,7 +1236,7 @@ class PriceModelController extends Controller
 
     public function apiStoreExpress()
     {
-        $this->gate("项目管理-项目-录入");
+        $this->gate("计费模型-快递-录入");
         $params = request()->input();
         $params["logistic_id"] = $params["logistics"];
         $errors = $this->expressValidator($params,request("id"))->errors()->toArray();
@@ -1249,6 +1253,7 @@ class PriceModelController extends Controller
             "additional_weight" => request("additional_weight"),
             "amount_interval"   => request("amount_interval"),
             "weight_interval"   => request("weight_interval"),
+            "tax_rate_id"       => request("tax_rate_id") ?? null,
         ];
         if (request("id")){
             /** @var \stdClass $model */
@@ -1307,7 +1312,7 @@ class PriceModelController extends Controller
 
     public function apiStoreLogistic()
     {
-        $this->gate("项目管理-项目-录入");
+        $this->gate("计费模型-物流-录入");
         $params = request()->input();
         $params["owner_id"] = [$params["owner_id"]];
         $params["logistic_id"] = $params["logistics"];
@@ -1329,6 +1334,7 @@ class PriceModelController extends Controller
             "pick_up_price"     => request('pick_up_price'),
             "fuel_price"        => request('fuel_price'),
             "service_price"     => request('service_price'),
+            "tax_rate_id"       => request("tax_rate_id") ?? null,
         ];
         if (request("id")){
             $model = app("OwnerPriceLogisticService")->find(request("id"),["details"]);
@@ -1388,7 +1394,7 @@ class PriceModelController extends Controller
 
     public function apiStoreDirectLogistic()
     {
-        $this->gate("项目管理-项目-录入");
+        $this->gate("计费模型-直发-录入");
         $errors = $this->directLogisticValidator(request()->input(),request("id"))->errors()->toArray();
         $exist = [];
         foreach (request("items") as $index=>$item){
@@ -1401,6 +1407,7 @@ class PriceModelController extends Controller
         $obj = [
             "name"      => request("name"),
             "base_km"   => request("base_km"),
+            "tax_rate_id"=> request("tax_rate_id") ?? null,
         ];
         if (request("id")){
             $model = app("OwnerPriceDirectLogisticService")->find(request("id"),["details"]);
@@ -1449,6 +1456,27 @@ class PriceModelController extends Controller
         $this->success($model);
     }
 
+    public function apiStoreSystem()
+    {
+        $this->gate("计费模型-系统-录入");
+        if (!request("owner_id") || !request("usage_fee") || \request("usage_fee")<0)$this->success(["errors"=>["usage_fee"=>["不得小于0"]]]);
+        if (request("id")){
+            /** @var OwnerPriceSystem|\stdClass $model */
+            $model = OwnerPriceSystem::query()->find(request("id"));
+            if ($model->operation)$model->update(["usage_fee"=>\request("usage_fee"),"operation"=>"U","tax_rate_id"=>\request("tax_rate_id")]);
+            else $model = OwnerPriceSystem::query()->create([
+                "usage_fee" => \request("usage_fee"),
+                "operation"=>"U",
+                "target_id"=>$model->id,
+                "owner_id"=>$model->owner_id,
+                "tax_rate_id"=>\request("tax_rate_id")
+            ]);
+        }else{
+            $model = OwnerPriceSystem::query()->create(["usage_fee" => \request("usage_fee"),"owner_id"=>request("owner_id"),"operation"=>"C","tax_rate_id"=>\request("tax_rate_id")]);
+        }
+        $this->success($model);
+    }
+
     public function getPriceModel()
     {
         /** @var Owner|\stdClass $owner */
@@ -1466,8 +1494,8 @@ class PriceModelController extends Controller
         },"ownerPriceLogistics"=>function($query){
             /** @var Builder $query */
             $query->with(["details","logistics"]);
-        },"ownerPriceDirectLogistics.details"]);
-        $owner->loadCount(["storageAudit","operationAudit","expressAudit","logisticAudit","directLogisticAudit"]);
+        },"ownerPriceDirectLogistics.details","ownerPriceSystem"]);
+        $owner->loadCount(["storageAudit","operationAudit","expressAudit","logisticAudit","directLogisticAudit","systemAudit"]);
         $features = app("FeatureService")->getMapArray();
         OwnerPriceOperation::$features = $features;
         OwnerPriceOperationItem::$features = $features;
@@ -1737,6 +1765,18 @@ class PriceModelController extends Controller
         }
         $this->success();
     }
+    public function apiDelSystem()
+    {
+        $this->gate("项目管理-系统-录入");
+        if (!request("id"))$this->error("非法参数");
+        /** @var OwnerPriceSystem|\stdClass $model */
+        $model = OwnerPriceSystem::query()->find(\request("id"));
+        if ($model->operation && $model->target_id){
+            OwnerPriceSystem::query()->where($model->target_id,\request("id"))->update(["operation"=>"D"]);
+            $model->delete();
+        }
+        $this->success();
+    }
 
     private function publicDeleteNode(string $serviceName)
     {
@@ -1811,7 +1851,25 @@ class PriceModelController extends Controller
                 $owner->load("ownerPriceDirectLogistics.details");
                 $this->success($owner->ownerPriceDirectLogistics);
                 break;
+            case "system":
+                $result = app(QueryService::class)->priceModelAuditOrRecoverQuery(request("isAudit"),OwnerPriceSystem::query(),$ownerId,null,true);
+                if ($result["delete"]){
+                    OwnerPriceSystem::destroy($result["delete"]);
+                    app("OwnerService")->refreshRelevance($ownerId,5,true);
+                }
+                if ($result["update"]){
+                    OwnerPriceSystem::query()->whereIn("id",$result["update"])->update(["operation"=>null,"target_id"=>null]);
+                    app("OwnerService")->refreshRelevance($ownerId,5);
+                }
+                $owner->load("ownerPriceSystem");
+                $this->success($owner->ownerPriceSystem);
+                break;
         }
     }
 
+    /**
+     * 获取审核对比信息
+     */
+
+
 }

+ 1 - 0
app/Http/Controllers/ProcurementController.php

@@ -21,6 +21,7 @@ use App\ProcurementDeliverie;
 use App\ProcurementTotalBill;
 use App\Services\common\ExportService;
 use App\Services\ConfigurationService;
+use App\Services\LogService;
 use App\Services\OwnerMaterialService;
 use App\Services\ProcurementService;
 use App\Services\ProcurementTotalBillService;

+ 15 - 56
app/Http/Controllers/TestController.php

@@ -176,6 +176,9 @@ class TestController extends Controller
     {
         return view("test");
     }
+    public function a(){
+        return array(null,null);
+    }
     public function supplementMarchOwnerReport()
     {
         $ows = OwnerAreaReport::query()->select("owner_id")->where("counting_month",'like',"2021-03%")->get();
@@ -1220,6 +1223,18 @@ where purch.islower=1');
         $count = OrderPackage::query()->where('status', '派送异常')->update(['exception_type' => '派件异常','exception' => '是']);
         dump('更新了: '.$count);
     }
+
+    public function order_packages_exception_type_and_exception_update()
+    {
+        $count_1 = OrderPackage::query()
+            ->whereIn('exception_type', ['疑似库内丢件','揽件异常'])
+            ->whereNotNull('transfer_status')
+            ->update(['exception_type' => '无','exception' => '否']);
+        $count_2 =   OrderPackage::query()
+            ->where('status','已收件')
+            ->update(['exception_type' => '无','exception' => '否']);
+        dump('更新了: '.($count_1 + $count_2));
+    }
     public function addProcurementDeliverAndCheckMeet()
     {
         $id=ProcurementDeliverie::query()->orderByDesc('id')->value('id');
@@ -1272,60 +1287,4 @@ where purch.islower=1 and deliver.id>'.$id);
         }
         ProcurementCheckSheet::query()->insert($insert_);
     }
-    public function testPro(){
-        /**@var SupplierService $supplierService*/
-        $supplierService=app(SupplierService::class);
-        $supplier_ids=$supplierService->screenSupplierIds();
-//        $status=0;
-//        $procurements=Procurement::query()
-//            ->withCount('procurementQuotations')
-//            ->with('ownerMaterial.material')
-//            ->where('status',$status)
-//            ->whereHas("ownerMaterial",function (Builder $query)use($supplier_ids){
-//                $query->whereHas("material",function (Builder $query)use($supplier_ids){
-//                    $query->whereHas("supplier",function (Builder $query)use($supplier_ids){
-//                        $query->whereIn('id',$supplier_ids);
-//                    });
-//                });
-//            })
-//            ->get();
-//        $keys = [];
-//        foreach ($procurements as $key=>$procurement){
-////            if ($procurement->procurement_quotations_count>0 && $status==0 )$keys[]= $key;
-//            if ($procurement->type==2 && $procurement->supplier_id )$keys[]= $key;
-//            if (Carbon::parse($procurement->deadline)->gt(Carbon::now())) $procurement->deadline=Carbon::parse($procurement->deadline)->diffInMilliseconds();
-//            else $procurement->deadline=0;
-//        }
-//        $procurements = $procurements->diffKeys($keys);
-//        dd($procurements);
-        $status=0;//0:待报价,2:待接单
-        $procurements=Procurement::query()
-            ->withCount('procurementQuotations')
-            ->with(['ownerMaterial.material','procurementQuotations'])
-            ->where('status',$status)
-            ->get();
-        dd($procurements);
-        $keys = [];
-        foreach ($procurements as $key=>$procurement){
-            if ($procurement->procurement_quotations_count>0 ){
-                foreach ($procurement->procurementQuotations as $procurementQuotation){
-                    if (in_array($procurementQuotation->supplier_id,$supplier_ids))$keys[]= $key;
-                }
-            }
-            if ($procurement->type==2 && $procurement->supplier_id )$keys[]= $key;
-            if (Carbon::parse($procurement->deadline)->gt(Carbon::now())) $procurement->deadline=Carbon::parse($procurement->deadline)->diffInMilliseconds();
-            else $procurement->deadline=0;
-        }
-        $procurements = $procurements->diffKeys($keys);
-        dd($procurements);
-    }
-
-    public function pushToWmsWeight()
-    {
-        $orderPackages = OrderPackage::query()->where('measuring_machine_id',12)->where('uploaded_to_wms','!=','是')->whereNotNull('weight')->get();
-        $packageController = new WeightBaseController();
-        foreach ($orderPackages as $orderPackage) {
-            $packageController->activityWaveNoProcessing($orderPackage);
-        }
-    }
 }

+ 5 - 5
app/Http/Controllers/UserController.php

@@ -42,11 +42,11 @@ class UserController extends Controller
         if($request->has('owner_id')){
             $owner_id= $request->input('owner_id');
             $owner_ids = array_filter(preg_split('/[,, ]+/is',$owner_id));
-            $ids=[];
-            foreach ($owner_ids as $id)$ids[]='_'.$id;
-            $query->whereHas('roles',function($query) use ($ids){
-                $query->whereHas('authorities',function ($query)use($ids){
-                    $query->whereIn('name',$ids);
+            $ownerIds=[];
+            foreach ($owner_ids as $id)$ownerIds[]='_'.$id;
+            $query->whereHas('roles',function($query) use ($ownerIds){
+                $query->whereHas('authorities',function ($query)use($ownerIds){
+                    $query->whereIn('name',$ownerIds);
                 });
             });
         }

+ 1 - 1
app/Http/Controllers/WaybillController.php

@@ -617,7 +617,7 @@ class WaybillController extends Controller
         if (request("checkAllSign")){
             request()->offsetUnset("checkAllSign");
             $waybills = app('waybillService')->get(request()->input());
-        }else $waybills = app('waybillService')->get(["id"=>request("id")]);
+        }else $waybills = app('waybillService')->get(["id"=>request("data")]);
         /** @var Collection $waybills */
         $row = [
             "运单类型", "货主", "上游单号", "wms订单号", "运单号", "运输收费",

+ 4 - 0
app/Http/Controllers/api/thirdPart/haiq/LightController.php

@@ -24,6 +24,10 @@ class LightController
     public function lightOff(Request $request){
     }
 
+    /**
+     * @param Request $request {"areaCode":"1004","locCode":"HAIB2-02-03","displayInfo":null,"PTLAction":0,"PTLSettings":null}
+     * @return array
+     */
     public function update(Request $request){
         $success = $request->input('success');
         $location = $success?200:0;

+ 40 - 11
app/Http/Controllers/api/thirdPart/weixin/ProcurementController.php

@@ -13,6 +13,7 @@ use App\Services\api\UserService;
 use App\Services\ProcurementService;
 use App\Services\SupplierService;
 use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
@@ -23,28 +24,46 @@ class ProcurementController extends Controller
 
     public function getWaitQuotation(Request $request): \Illuminate\Http\JsonResponse
     {
+        $user=Auth::user();
         /**@var SupplierService $supplierService*/
         $supplierService=app(SupplierService::class);
         $supplier_ids=$supplierService->screenSupplierIds();
         $status=$request->input('status');//0:待报价,2:待接单
-        $procurements=Procurement::query()
-            ->withCount('procurementQuotations')
-            ->with(['ownerMaterial.material','procurementQuotations'])
-            ->where('status',$status)
-            ->get();
-        $keys = [];
+        switch ($status){
+            case 0:
+                $procurements=Procurement::query()
+                    ->withCount('procurementQuotations')
+                    ->with('ownerMaterial.material')
+                    ->where('status',$status)
+                    ->whereHas("ownerMaterial",function (Builder $query)use($supplier_ids){
+                        $query->whereHas("material",function (Builder $query)use($supplier_ids){
+                            $query->whereHas("supplier",function (Builder $query)use($supplier_ids){
+                                $query->whereIn('id',$supplier_ids);
+                            });
+                        });
+                    })
+                    ->get();
+                break;
+            case 2:
+                $procurements=Procurement::query()
+                    ->withCount('procurementQuotations')
+                    ->with('ownerMaterial.material')
+                    ->where('status',$status)
+                    ->whereIn('supplier_id',$supplier_ids)
+                    ->get();
+                break;
+        }
+        if (!isset($procurements))return $this->error('未查到相应单据');
         foreach ($procurements as $key=>$procurement){
-//            if ($procurement->procurement_quotations_count>0 && $status==0 )$keys[]= $key;
-            if ($procurement->procurement_quotations_count>0 ){
+            if ($status==0 && $procurement->procurement_quotations_count>0 && !$user->isSuperAdmin()){
                 foreach ($procurement->procurementQuotations as $procurementQuotation){
-                    if (in_array($procurementQuotation->supplier_id,$supplier_ids))$keys[]= $key;
+                    if (in_array($procurementQuotation->supplier_id,$supplier_ids))unset($procurements[$key]);
                 }
             }
-            if ($procurement->type==2 && $procurement->supplier_id )$keys[]= $key;
+            if ($procurement->type==2 && $procurement->supplier_id )unset($procurements[$key]);
             if (Carbon::parse($procurement->deadline)->gt(Carbon::now())) $procurement->deadline=Carbon::parse($procurement->deadline)->diffInMilliseconds();
             else $procurement->deadline=0;
         }
-        $procurements = $procurements->diffKeys($keys);
         if (!empty($procurements)) return $this->success($procurements);
     }
 
@@ -105,10 +124,14 @@ class ProcurementController extends Controller
     //生产中的订单
     public function getProductionProcurement(): \Illuminate\Http\JsonResponse
     {
+        /**@var SupplierService $supplierService*/
+        $supplierService=app(SupplierService::class);
+        $supplier_ids=$supplierService->screenSupplierIds();
         $procurements=Procurement::query()
             ->with('ownerMaterial.material')
             ->whereIn('type',[0,2])
             ->where('status',4) //4:生产中
+            ->whereIn('supplier_id',$supplier_ids)
             ->get();
         if ($procurements) return $this->success($procurements);
     }
@@ -122,9 +145,15 @@ class ProcurementController extends Controller
 
     public function getProcurementDeliveries(): \Illuminate\Http\JsonResponse
     {
+        /**@var SupplierService $supplierService*/
+        $supplierService=app(SupplierService::class);
+        $supplier_ids=$supplierService->screenSupplierIds();
         $procurementDeliveries=ProcurementDeliverie::query()
             ->with('procurement.ownerMaterial.material')
             ->whereIn('status',[0,1])//1:待送货,2:送货中
+            ->whereHas('procurement',function (Builder $query)use($supplier_ids){
+                $query->whereIn('supplier_id',$supplier_ids);
+            })
             ->get();
         $procurementDeliveries=$procurementDeliveries->filter(function ($item){
             return isset($item->procurement);

+ 8 - 0
app/Jobs/LogisticZopSync.php

@@ -98,6 +98,14 @@ class LogisticZopSync implements ShouldQueue
             unset($resultItem['status']);
             unset($resultItem['transfer_status']);
         }
+        //如果没有发现额外的异常,且查询到物流轨迹,将异常置为无
+        if (!array_key_exists('exception', $resultItem)
+            && !array_key_exists('exception_type', $resultItem)
+            && array_key_exists('transfer_status', $resultItem)
+        ) {
+            $resultItem['exception_type'] = '无';
+            $resultItem['exception'] = '否';
+        }
         $result[] = $resultItem;
         return $result;
     }

+ 2 - 2
app/Jobs/ProcurementConfirmInform.php

@@ -34,8 +34,8 @@ class ProcurementConfirmInform implements ShouldQueue
     public function handle()
     {
         $pro=$this->procurement->loadMissing(['ownerMaterial.material.supplier.user.userDetail','ownerMaterial.owner.customer']);
-        if (empty($pro->ownerMaterial->material->supplier))return;
-        $suppliers=$pro->ownerMaterial->material->supplier;
+        $suppliers=$pro->ownerMaterial->material->supplier ?? false;
+        if(!$suppliers) return ;
         $open_ids=[];
         foreach ($suppliers as $supplier) {
             foreach ($supplier->user as $user){

+ 39 - 16
app/Jobs/ResetInstantBill.php

@@ -61,43 +61,58 @@ class ResetInstantBill implements ShouldQueue
                 $volume = 0;
                 $weight = 0;
                 $logistic_bill = "";
+
                 if (!$order->logistic || $order->logistic->type == "物流")$logistic_fee = null;
+
                 $items = [];
+                $isBunched = $order->logistic->is_bunched=='Y';
+                $weightExceptionMark = false;
+                $provinceId = null;
+                $logisticTaxFee = 0;
                 foreach ($order->packages as &$package){
+                    $tax = 0;
+
                     $logistic_bill .= $package->logistic_number.",";
                     $volume += $package->bulk;
                     $weight += $package->weight;
+                    if (!$weightExceptionMark && (!$package->weight || $package->weight<0))$weightExceptionMark = true;
                     $partAmount = 0;
                     foreach($package->commodities as $commodity){
                         $partAmount += $commodity->amount;
                     }
                     $amount += $partAmount;
+
                     $provinceName = mb_substr($order->province,0,2);
                     $province = app(CacheService::class)->getOrExecute("province_".$provinceName,function ()use($provinceName){
                         return Province::query()->where("name","like",$provinceName."%")->first();
                     },86400);
+                    $fee = null;
                     if ($province){
-                        $fee = $service->matching($package->weight, $order->owner_id, $order->logistic_id, $province->id);
-                    }else{
-                        $logistic_fee = null;
-                        $fee = null;
-                    }
+                        if (!$provinceId)$provinceId = $province->id;
+                        else if ($provinceId!=$province->id)$weightExceptionMark = true;
+                        if (!$isBunched)list($fee,$tax) = $service->matching($package->weight, $order->owner_id, $order->logistic_id, $province->id);
+                    }else $logistic_fee = null;
+
                     $items[] = [
                         "amount" => $partAmount,
                         "logistic_bill" => $package->logistic_number,
                         "volume"=>$package->bulk,
                         "weight"=>$package->weight,
-                        "logistic_fee" => $fee>0 ? $fee : null,
+                        "logistic_fee" => $fee,
+                        "tax_fee" => $tax,
                     ];
                     if ($logistic_fee!==null){
-                        if ($fee<0)$logistic_fee = null;
+                        if (!$fee || $fee<0)$logistic_fee = null;
                         else $logistic_fee += $fee;
                     }
+                    $logisticTaxFee += $tax;
                 }
+                /* 为字母单 且 重量与省份完整 且 重量大于0 且 省份存在 进入子母单计算 */
+                if ($isBunched && !$weightExceptionMark && $weight>0 && $provinceId)list($logistic_fee,$logisticTaxFee) = $service->matching($weight, $order->owner_id, $order->logistic_id, $provinceId);
                 if ($logistic_fee!==null && $logistic_fee<0)$logistic_fee = null;
                 /** @var OwnerPriceOperationService $service */
                 $service = app("OwnerPriceOperationService");
-                $result = $service->matching($order,Feature::MAPPING["order"],$order->owner_id,"出库");
+                list($id,$money,$workTaxFee) = $service->matching($order,Feature::MAPPING["order"],$order->owner_id,"出库");
 
                 $detail = $this->detail->update([
                     "owner_id"          => $order->owner_id,
@@ -111,9 +126,11 @@ class ResetInstantBill implements ShouldQueue
                     "volume"            => $volume,
                     "weight"            => $weight,
                     "logistic_id"       => $order->logistic_id,
-                    "work_fee"          => is_array($result) ? ($result["money"]>0 ? $result["money"] : null) : null,
-                    "owner_price_operation_id"  => is_array($result) ? $result["id"] : null,
+                    "work_fee"          => $money,
+                    "owner_price_operation_id"  => $id,
                     "logistic_fee"      => $logistic_fee,
+                    "work_tax_fee"      => $workTaxFee,
+                    "logistic_tax_fee"  => $logistic_fee ? $logisticTaxFee : null,
                 ]);
                 if ($detail){
                     OwnerFeeDetailLogistic::query()->where("owner_fee_detail_id",$detail->id)->delete();
@@ -136,20 +153,25 @@ class ResetInstantBill implements ShouldQueue
                 if (!$waybill->destinationCity && !$waybill->order)break;
 
                 $owner_id = $waybill->order->owner_id ?? $waybill->owner_id;
+                $detail = OwnerFeeDetail::query()->where("type","发货")
+                    ->where("owner_id",$owner_id)->whereIn("operation_bill",[$waybill->wms_bill_number,$waybill->waybill_number])->first();
+
+                if ($detail && $detail->logistic_fee !== null)break;
 
                 if ($waybill->type == "专线"){
                     /** @var OwnerPriceLogisticService $service */
                     $service = app("OwnerPriceLogisticService");
-                    $fee = $service->matching($waybill->carrier_weight_other,$owner_id,$waybill->logistic_id,
+                    list($fee,$taxFee) = $service->matching($waybill->carrier_weight_other,$owner_id,$waybill->logistic_id,
                         $waybill->carrier_weight_unit_id_other,$waybill->order ? app("RegionService")->getProvince($waybill->order->province) : $waybill->destinationCity->province_id,
                         $waybill->destination_city_id);
                 }else{
                     /** @var OwnerPriceDirectLogisticService $service */
                     $service = app("OwnerPriceDirectLogisticService");
-                    $fee = $service->matching($waybill->mileage,$owner_id,$waybill->carType_id);
+                    list($fee,$taxFee) = $service->matching($waybill->mileage,$owner_id,$waybill->carType_id);
                 }
                 $this->detail->update([
-                    "logistic_fee" => $fee ?? null,
+                    "logistic_fee" => $fee,
+                    "logistic_tax_fee" => $taxFee,
                 ]);
                 break;
             case "stores":
@@ -160,14 +182,15 @@ class ResetInstantBill implements ShouldQueue
 
                 /** @var OwnerPriceOperationService $service */
                 $service = app("OwnerPriceOperationService");
-                $result = $service->matching($store, Feature::MAPPING["store"], $store->owner_id, "入库");
+                list($id,$money,$taxFee) = $service->matching($store, Feature::MAPPING["store"], $store->owner_id, "入库");
                 $this->detail->update([
                     "owner_id" => $store->owner_id,
                     "worked_at" => $store->created_at,
                     "operation_bill" => $store->asn_code,
                     "commodity_amount" => array_sum(array_column($store->storeItems->toArray(), "amount")),
-                    "work_fee" => is_array($result) ? ($result["money"]>0 ? $result["money"] : null) : null,
-                    "owner_price_operation_id" => is_array($result) ? $result["id"] : null,
+                    "work_fee" => $money,
+                    "owner_price_operation_id" => $id,
+                    "work_tax_fee" => $taxFee
                 ]);
                 break;
         }

+ 9 - 11
app/Listeners/AddOrUpdateOrderIssuesListener.php

@@ -3,11 +3,11 @@
 namespace App\Listeners;
 
 use App\Events\AddOrUpdateOrderIssues;
+use App\OrderIssue;
 use App\OrderPackage;
 use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Queue\InteractsWithQueue;
 
-class AddOrUpdateOrderIssuesListener
+class AddOrUpdateOrderIssuesListener implements ShouldQueue
 {
     /**
      * Create the event listener.
@@ -27,15 +27,13 @@ class AddOrUpdateOrderIssuesListener
      */
     public function handle(AddOrUpdateOrderIssues $event)
     {
-        $order_ids = $event->order_ids;
-        OrderPackage::query()
-            ->whereIn('order_id', $order_ids)
-            ->whereHas('order.issue.issueType', function ($query) {
-                $query->whereNotIn('name', ['拦截', '信息更改', '其他', '错漏发', '仓库问题', '二次加工', '全检问题', '系统问题', '快递方式更改']);
-            })
+        OrderPackage::query()->whereIn('order_id',
+            OrderIssue::query()->select('order_id')->whereIn('order_id', $event->order_ids)->whereIn('order_issue_type_id', function ($query) {
+            $query->from('order_issue_types')->select('id')->whereNotIn('name', ['拦截', '信息更改', '其他', '错漏发', '仓库问题', '二次加工', '全检问题', '系统问题', '快递方式更改']);
+        }))
             ->update([
-                'exception_type' => '其他',
-                'exception' => '是',
-            ]);
+            'exception_type' => '其他',
+            'exception' => '是',
+        ]);
     }
 }

+ 1 - 1
app/Logistic.php

@@ -17,7 +17,7 @@ class Logistic extends Model
     use ModelLogChanging;
     use SoftDeletes;
     use ModelTimeFormat;
-    protected $fillable = ['name','code',"type","mobile","remark","delivery_fee"];
+    protected $fillable = ['name','code',"type","mobile","remark","delivery_fee","is_bunched"];
 
 
     static function nameById($id){

+ 17 - 1
app/Owner.php

@@ -36,7 +36,7 @@ class Owner extends Model
         "relevance",             //关联模型的JSON数组
         'subjection'             //主体公司
     ];
-    //relevance说明 0:仓储 1:作业 2:快递 3:物流 4:直发 存储示例:["0","1"]存在仓储与作业计费
+    //relevance说明 0:仓储 1:作业 2:快递 3:物流 4:直发 5:系统 存储示例:["0","1"]存在仓储与作业计费
     protected $casts = [
         "relevance" => "array"
     ];
@@ -150,6 +150,16 @@ class Owner extends Model
                 $query->where("operation","!=","D")->orWhereNull("operation");
             });
     }
+    public function ownerPriceSystem()
+    {   //系统计费
+        $query = OwnerPriceSystem::query()->select("target_id")
+            ->whereNotNull("operation")->where("operation","!=","")
+            ->whereNotNull("target_id")->where("target_id","!=","");
+        return $this->hasOne(OwnerPriceSystem::class,"owner_id","id")
+            ->whereNotIn("id",$query)->where(function(Builder $query){
+                $query->where("operation","!=","D")->orWhereNull("operation");
+            });
+    }
     public function warehouse()
     {   //仓库
         return $this->belongsTo(Warehouse::class,"warehouse_id","id");
@@ -197,4 +207,10 @@ class Owner extends Model
             ->where("operation","!=","")
             ->limit(1);
     }
+    public function systemAudit()
+    {   //审核的直发模型
+        return $this->hasOne(OwnerPriceSystem::class,"owner_id","id")
+            ->select(DB::raw(1))->whereNotNull("operation")
+            ->where("operation","!=","");
+    }
 }

+ 2 - 1
app/OwnerBillReport.php

@@ -19,6 +19,7 @@ class OwnerBillReport extends Model
        "confirm_fee",    //确认账单金额
        "difference",     //差额
        "confirmed",      //确认状态
+       "other_fee",      //其他费用
    ];
    protected $appends=[
         "initial_fee"
@@ -39,6 +40,6 @@ class OwnerBillReport extends Model
     }
     public function getInitialFeeAttribute()
     {   //初始账单金额
-        return $this->work_fee + $this->logistic_fee + $this->storage_fee;
+        return $this->work_fee + $this->logistic_fee + $this->storage_fee + $this->other_fee;
     }
 }

+ 2 - 0
app/OwnerFeeDetail.php

@@ -30,6 +30,8 @@ class OwnerFeeDetail extends Model
         "created_at",       //创建时间
         "outer_id",         //关联表ID
         "outer_table_name", //关联表名
+        "work_tax_fee",     //作业税费
+        "logistic_tax_fee", //物流税费
     ];
     public $timestamps = false;
 

+ 1 - 1
app/OwnerFeeDetailLogistic.php

@@ -11,7 +11,7 @@ class OwnerFeeDetailLogistic extends Model
     use ModelLogChanging;
 
     protected $fillable=[
-      "owner_fee_detail_id","amount","logistic_bill","volume","weight","logistic_fee"
+      "owner_fee_detail_id","amount","logistic_bill","volume","weight","logistic_fee","tax_fee"
     ];
 
     public $timestamps = false;

+ 5 - 1
app/OwnerPriceDirectLogistic.php

@@ -16,7 +16,7 @@ class OwnerPriceDirectLogistic extends Model
         "base_km",  //起步公里数
         "operation",//操作
         "target_id",//目标ID
-
+        "tax_rate_id",//税率
     ];
 
     public function details()
@@ -27,6 +27,10 @@ class OwnerPriceDirectLogistic extends Model
     {   //货主中间表
         return $this->belongsToMany(Owner::class,"owner_price_direct_logistic_owner","owner_price_direct_logistic_id","owner_id");
     }
+    public function taxRate()
+    {   //税率
+        return $this->belongsTo(TaxRate::class);
+    }
 
     public function getOwnerIdAttribute()
     {   //获取货主ID数组

+ 5 - 0
app/OwnerPriceExpress.php

@@ -19,6 +19,7 @@ class OwnerPriceExpress extends Model
         "target_id",        //目标ID
         "amount_interval",  //数量区间
         "weight_interval",  //重量区间
+        "tax_rate_id",      //税率
     ];
     protected $casts = [
         "amount_interval" => "array",
@@ -37,6 +38,10 @@ class OwnerPriceExpress extends Model
     {   //计费详情
         return $this->hasMany(OwnerPriceExpressProvince::class,"owner_price_express_id","id");
     }
+    public function taxRate()
+    {   //税率
+        return $this->belongsTo(TaxRate::class);
+    }
 
     public function getOwnerIdAttribute()
     {   //获取货主ID数组

+ 5 - 0
app/OwnerPriceLogistic.php

@@ -22,6 +22,7 @@ class OwnerPriceLogistic extends Model
         "service_price",    //信息服务费
         "operation",        //操作
         "target_id",        //目标ID
+        "tax_rate_id",      //税率
     ];
 
     public function getUnitRangeJsonAttribute()
@@ -53,6 +54,10 @@ class OwnerPriceLogistic extends Model
     {   //物流
         return $this->belongsToMany(Logistic::class,"owner_price_logistic_logistic","owner_price_logistic_id","logistic_id");
     }
+    public function taxRate()
+    {   //税率
+        return $this->belongsTo(TaxRate::class);
+    }
 
     public function getOwnerIdAttribute()
     {   //获取货主ID数组

+ 5 - 0
app/OwnerPriceOperation.php

@@ -26,6 +26,7 @@ class OwnerPriceOperation extends Model
         "surcharge",        //附加费
         "surcharge_unit_id",//附加费单位
         "max_fee",          //封顶费
+        "tax_rate_id",      //税率
     ];
     public static $features = null;
     public static $columnMapping = null;
@@ -41,6 +42,10 @@ class OwnerPriceOperation extends Model
     {   //货主
         return $this->belongsToMany(Owner::class,"owner_price_operation_owner","owner_price_operation_id","owner_id");
     }
+    public function taxRate()
+    {   //税率
+        return $this->belongsTo(TaxRate::class);
+    }
 
     public function getFeatureFormatAttribute()
     {

+ 16 - 0
app/OwnerPriceSystem.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class OwnerPriceSystem extends Model
+{
+    use ModelLogChanging;
+
+    protected $fillable=[
+        "owner_id","usage_fee","operation","target_id","tax_rate_id"
+    ];
+}

+ 5 - 0
app/OwnerStoragePriceModel.php

@@ -23,6 +23,7 @@ class OwnerStoragePriceModel extends Model
         "operation",        //操作
         "target_id",        //目标ID
         "amount_interval",  //数量区间
+        "tax_rate_id",      //税率
     ];
     protected $casts = [
         "amount_interval" => "array",
@@ -41,4 +42,8 @@ class OwnerStoragePriceModel extends Model
     {   //计时单位
         return $this->belongsTo(Unit::class,"time_unit_id");
     }
+    public function taxRate()
+    {   //税率
+        return $this->belongsTo(TaxRate::class);
+    }
 }

+ 40 - 26
app/Procurement.php

@@ -29,7 +29,7 @@ class Procurement extends Model
         1 => "已报价",
         2 => "待接单",
         3 => "已失效",
-        4 => "生中",
+        4 => "生中",
         5 => "待收货",
         6 => "待确定",
         7 => "待出账",
@@ -71,29 +71,43 @@ class Procurement extends Model
         return $filters->apply($query);
     }
 
-    protected static function booted()
-    {
-        /** @var User $user */
-        $user = Auth::user();
-        if (Gate::allows('供应商-可见全部'))return;
-        if ($user && !$user->isSuperAdmin()){
-            /** @var \stdClass $user */
-            $ids = array_column(DB::select(DB::raw("SELECT supplier_id FROM supplier_user WHERE user_id = ?"),[$user->id]),"supplier_id");
-            if (count($ids)>0){
-                static::addGlobalScope('supplier', function (Builder $builder)use ($ids) {
-                    $builder->where(function (Builder $query)use($ids){
-                        $query->where(function (Builder $query)use($ids){
-                            $query->whereNull("supplier_id")->orWhereIn('supplier_id',$ids)->orWhere("type",1);
-                        })->orWhereHas("ownerMaterial",function (Builder $query)use($ids){
-                            $query->whereHas("material",function (Builder $query)use($ids){
-                                $query->whereHas("supplier",function (Builder $query)use($ids){
-                                    $query->whereIn('id',$ids);
-                                });
-                            });
-                        });
-                    });
-                });//采购单 供应商为空 -》 耗材的供应商存在于IDS   供应商存在 -》 供应商本身存在于IDS
-            }
-        }
-    }
+//    protected static function booted()
+//    {
+//        /** @var User $user */
+//        $user = Auth::user();
+//        if (Gate::allows('供应商-可见全部'))return;
+//        if ($user && !$user->isSuperAdmin()){
+//            /** @var \stdClass $user */
+//            $ids = array_column(DB::select(DB::raw("SELECT supplier_id FROM supplier_user WHERE user_id = ?"),[$user->id]),"supplier_id");
+//            if (count($ids)>0){
+//                static::addGlobalScope('supplier', function (Builder $builder)use ($ids) {
+//                    $builder->where(function (Builder $query)use($ids){
+//                        $query->where(function (Builder $query)use($ids){
+//                            $query->whereNull("supplier_id")->orWhereIn('supplier_id',$ids)->orWhere("type",1);
+//                        })->WhereHas("ownerMaterial",function (Builder $query)use($ids){
+//                            $query->whereHas("material",function (Builder $query)use($ids){
+//                                $query->whereHas("supplier",function (Builder $query)use($ids){
+//                                    $query->whereIn('id',$ids);
+//                                });
+//                            });
+//                        });
+//                    });
+//                });//采购单 供应商为空 -》 耗材的供应商存在于IDS   供应商存在 -》 供应商本身存在于IDS
+//            }
+//        }
+//    }
+//    protected static function booted()
+//    {
+//        /** @var User $user */
+//        $user = Auth::user();
+//        if ($user && !$user->isSuperAdmin()) {
+//            /** @var \stdClass $user */
+//            $ids = array_column(DB::select(DB::raw("SELECT supplier_id FROM supplier_user WHERE user_id = ?"),[$user->id]),"supplier_id");
+//            if (count($ids)>0){
+//                static::addGlobalScope('supplier', function (Builder $builder)use ($ids) {
+//                    $builder->whereIn('supplier_id',$ids);
+//                });
+//            }
+//        }
+//    }
 }

+ 9 - 7
app/Services/InventoryAccountService.php

@@ -592,13 +592,15 @@ class InventoryAccountService
             array_push($inventoryAccountMissions,$inventoryAccountMission);
         }
         app('LogService')->log(__METHOD__,"批量跳过或确认差异",json_encode($checkData));
-        $inventoryAccount=InventoryAccount::query()->find($inventoryAccountId);
-        $inventoryAccount->processed=$inventoryAccount->getProcessedAmount();//已盘点数
-        $inventoryAccount->difference=$inventoryAccount->getDifferenceAmount();//盘点差异数
-        $inventoryAccount->returned=$inventoryAccount->getReturnedAmount(); //复盘归位数
-        $inventoryAccount->ignored=$inventoryAccount->getIgnoredAmount();
-        $inventoryAccount->update();
-        Controller::logS(__METHOD__,'批量跳过或确认差异修改盘点任务信息'.__FUNCTION__,json_encode($inventoryAccountId));
+        if ($inventoryAccountId){
+            $inventoryAccount=InventoryAccount::query()->find($inventoryAccountId);
+            $inventoryAccount->processed=$inventoryAccount->getProcessedAmount();//已盘点数
+            $inventoryAccount->difference=$inventoryAccount->getDifferenceAmount();//盘点差异数
+            $inventoryAccount->returned=$inventoryAccount->getReturnedAmount(); //复盘归位数
+            $inventoryAccount->ignored=$inventoryAccount->getIgnoredAmount();
+            $inventoryAccount->update();
+            Controller::logS(__METHOD__,'批量跳过或确认差异修改盘点任务信息'.__FUNCTION__,json_encode($inventoryAccountId));
+        }
         return $inventoryAccountMissions;
     }
     public function searchCommodityByBarcode($barcode,$owner_code){

+ 4 - 3
app/Services/LogService.php

@@ -60,18 +60,19 @@ class LogService
         while (Redis::LLEN('LOGS') > 0) {
             $log = Redis::LPOP('LOGS');
             $arr = json_decode($log);
-            if ($length + strlen($arr->description) > 1024 * 512) {
+            $description = (is_string($arr->description)?$arr->description:json_encode($arr->description))??'';
+            if ($length + strlen($description) > 1024 * 512) {
                 Log::query()->insert($data);
                 $length = 0;
                 $data = [];
             }
-            $length = $length + strlen($arr->description);
+            $length = $length + strlen($description);
             $data[] = [
                 'class' => $arr->class,
                 'id_user' => $arr->id_user,
                 'ip' => $arr->ip,
                 'method' => $arr->method,
-                'description' => $arr->description,
+                'description' => $description,
                 'created_at' => $arr->created_at,
                 'updated_at' => $arr->updated_at,
             ];

+ 8 - 0
app/Services/LogisticSFService.php

@@ -103,6 +103,14 @@ xml;
             if (!array_key_exists('exception', $data)) {//当顺丰返回异常时,不需要再根据时间判断是否异常,直接用顺丰的异常就好
                 $data = $this->setExceptionType($data, $lastRoute['accept_time']);
             }
+            //如果没有发现额外的异常,且查询到物流轨迹,将异常置为无
+            if (!array_key_exists('exception', $data)
+                && !array_key_exists('exception_type', $data)
+                && array_key_exists('transfer_status', $data)
+            ) {
+                $data['exception_type'] = '无';
+                $data['exception'] = '否';
+            }
         } catch (Exception $e) {
             throw new WarningException("单号没有查询到快递路由信息','LogisticSFService->transformSFOneToArr->{$data['logistic_number']}");
         } finally {

+ 42 - 22
app/Services/OrderService.php

@@ -1096,11 +1096,17 @@ sql
         if (!$order->logistic || $order->logistic->type == "物流")$logistic_fee = null;
 
         $items = [];
+        $isBunched = $order->logistic->is_bunched=='Y';
+        $weightExceptionMark = false;
+        $provinceId = null;
+        $logisticTaxFee = 0;
         foreach ($order->packages as &$package){
+            $tax = 0;
+
             $logistic_bill .= $package->logistic_number.",";
             $volume += $package->bulk;
             $weight += $package->weight;
-
+            if (!$weightExceptionMark && (!$package->weight || $package->weight<0))$weightExceptionMark = true;
             $partAmount = 0;
             foreach($package->commodities as $commodity){
                 $partAmount += $commodity->amount;
@@ -1111,30 +1117,33 @@ sql
             $province = app(CacheService::class)->getOrExecute("province_".$provinceName,function ()use($provinceName){
                 return Province::query()->where("name","like",$provinceName."%")->first();
             },86400);
+            $fee = null;
             if ($province){
-                $fee = $service->matching($package->weight, $order->owner_id, $order->logistic_id, $province->id);
-            }else{
-                $logistic_fee = null;
-                $fee = null;
-            }
+                if (!$provinceId)$provinceId = $province->id;
+                else if ($provinceId!=$province->id)$weightExceptionMark = true;
+                if (!$isBunched)list($fee,$tax) = $service->matching($package->weight, $order->owner_id, $order->logistic_id, $province->id);
+            }else $logistic_fee = null;
 
             $items[] = [
                 "amount" => $partAmount,
                 "logistic_bill" => $package->logistic_number,
                 "volume"=>$package->bulk,
                 "weight"=>$package->weight,
-                "logistic_fee" => $fee>0 ? $fee : null,
+                "logistic_fee" => $fee,
+                "tax_fee" => $tax,
             ];
             if ($logistic_fee!==null){
-                if ($fee<0)$logistic_fee = null;
+                if (!$fee || $fee<0)$logistic_fee = null;
                 else $logistic_fee += $fee;
             }
+            $logisticTaxFee += $tax;
         }
+        /* 为字母单 且 重量与省份完整 且 重量大于0 且 省份存在 进入子母单计算 */
+        if ($isBunched && !$weightExceptionMark && $weight>0 && $provinceId)list($logistic_fee,$logisticTaxFee) = $service->matching($weight, $order->owner_id, $order->logistic_id, $provinceId);
         if ($logistic_fee!==null && $logistic_fee<0)$logistic_fee = null;
-
         /** @var OwnerPriceOperationService $service */
         $service = app("OwnerPriceOperationService");
-        $result = $service->matching($order,Feature::MAPPING["order"],$order->owner_id,"出库");
+        list($id,$money,$workTaxFee) = $service->matching($order,Feature::MAPPING["order"],$order->owner_id,"出库");
 
         $detail = app("OwnerFeeDetailService")->create([
             "owner_id"          => $order->owner_id,
@@ -1149,12 +1158,14 @@ sql
             "volume"            => $volume,
             "weight"            => $weight,
             "logistic_id"       => $order->logistic_id,
-            "work_fee"          => is_array($result) ? ($result["money"]>0 ? $result["money"] : null) : null,
-            "owner_price_operation_id"  => is_array($result) ? $result["id"] : null,
+            "work_fee"          => $money,
+            "owner_price_operation_id"  => $id,
             "logistic_fee"      => $logistic_fee,
             "created_at"        => date('Y-m-d H:i:s'),
             "outer_id"          => $order->id,
             "outer_table_name"  => "orders",
+            "work_tax_fee"      => $workTaxFee,
+            "logistic_tax_fee"  => $logistic_fee ? $logisticTaxFee : null,
        ]);
        if ($detail){
             foreach ($items as &$item)$item["owner_fee_detail_id"] = $detail->id;
@@ -1262,19 +1273,28 @@ sql
         $volume = 0;
         $weight = 0;
         if (!$order->logistic || $order->logistic->type != "快递")$logistic_fee = null;
+        $isBunched = $order->logistic->is_bunched=='Y';
+        $weightExceptionMark = false;
+        $provinceId = null;
+        $taxFee = 0;
         foreach ($order->packages as $package){
+            $tax = 0;
+
             $volume += $package->bulk;
             $weight += $package->weight;
+            if (!$weightExceptionMark && (!$package->weight || $package->weight<0))$weightExceptionMark = true;
+            $fee = null;
 
             $provinceName = mb_substr($order->province,0,2);
+            $province = app(CacheService::class)->getOrExecute("province_".$provinceName,function ()use($provinceName){
+                return Province::query()->where("name","like",$provinceName."%")->first();
+            },86400);
             $fee = null;
-            if ($provinceName){
-                $province = app(CacheService::class)->getOrExecute("province_".$provinceName,function ()use($provinceName){
-                    return Province::query()->where("name","like",$provinceName."%")->first();
-                },86400);
-                if (!$province)$logistic_fee = null;
-                else $fee = app("OwnerPriceExpressService")->matching($package->weight, $order->owner_id, $order->logistic_id, $province->id);
-            }
+            if ($province){
+                if (!$provinceId)$provinceId = $province->id;
+                else if ($provinceId!=$province->id)$weightExceptionMark = true;
+                if (!$isBunched)list($fee,$tax) = app("OwnerPriceExpressService")->matching($package->weight, $order->owner_id, $order->logistic_id, $province->id);
+            }else $logistic_fee = null;
 
             OwnerFeeDetailLogistic::query()->where("owner_fee_detail_id",$feeBill->id)->where("logistic_bill",$package->logistic_number)->update([
                 "volume"=>$package->bulk,
@@ -1285,10 +1305,10 @@ sql
                 if ($fee<0)$logistic_fee = null;
                 else $logistic_fee += $fee;
             }
+            $taxFee += $tax;
         }
-        if ($logistic_fee===null || $logistic_fee<0)
-            LogService::log(__METHOD__,"ERROR-校正即时账单计算物流费错误","订单ID:".$order->id."  费用结果:".$logistic_fee);
-        else $feeBill->update(["logistic_fee"=>$logistic_fee,"volume"=>$volume,"weight"=>$weight]);
+        if ($isBunched && !$weightExceptionMark && $weight>0 && $provinceId)list($logistic_fee,$taxFee) = app("OwnerPriceExpressService")->matching($weight, $order->owner_id, $order->logistic_id, $provinceId);
+        if ($logistic_fee!==null && $logistic_fee>0) $feeBill->update(["logistic_fee"=>$logistic_fee,"volume"=>$volume,"weight"=>$weight,"logistic_tax_fee"=>$taxFee]);
         return true;
     }
 

+ 5 - 4
app/Services/OwnerPriceDirectLogisticService.php

@@ -174,12 +174,11 @@ class OwnerPriceDirectLogisticService
 
 
     /**
-     * CODE: -1:未找到计费模型
      *
      * @param double $amount
      * @param integer $owner_id
      * @param integer $car_id
-     * @return double
+     * @return array
      */
     public function matching($amount, $owner_id, $car_id)
     {
@@ -192,10 +191,12 @@ class OwnerPriceDirectLogisticService
         })->where(function(Builder $query){
             $query->whereNull("operation")->orWhere("operation","");
         })->first();
-        if (!$model || !$model->details)return -1;
+        if (!$model || !$model->details)return array(null,null);
         if ($amount < $model->base_km)$amount = $model->base_km;
         $initialMoney = $model->details[0]->base_fee;
         $amount -= $model->base_km;
-        return ($amount*$model->details[0]->additional_fee)+$initialMoney;
+        $money = ($amount*$model->details[0]->additional_fee)+$initialMoney;
+        $taxFee = $model->tax_rate_id && $model->taxRate ? $money*($model->taxRate->value/100) : null;
+        return array($money,$taxFee);
     }
 }

+ 6 - 5
app/Services/OwnerPriceExpressService.php

@@ -234,17 +234,16 @@ sql
     }
 
     /**
-     * CODE: -1:未找到计费模型 -2:重量无效
      *
      * @param double $weight
      * @param integer $owner_id
      * @param integer $logistic_id
      * @param integer $province_id
-     * @return double
+     * @return array
      */
     public function matching($weight, $owner_id, $logistic_id, $province_id)
     {
-        if (!$weight)return -2;
+        if (!$weight)return array(null,null);
 
         $model = OwnerPriceExpress::query()->with(["details"=>function($query)use($province_id){
             /** @var Builder $query */
@@ -258,7 +257,7 @@ sql
         })->where(function(Builder $query){
             $query->whereNull("operation")->orWhere("operation","");
         })->first();
-        if (!$model || count($model->details)<1)return -1;
+        if (!$model || count($model->details)<1)return array(null,null);
 
         if ($model->amount_interval){
             $total = app("OrderService")->getOrderQuantity($owner_id);//获取该货主本月C端单量
@@ -278,6 +277,8 @@ sql
         $additionalPrice = $model->details[0]->additional_weight_price[$to1][$to2];
         if ($weight <= $model->initial_weight)return $initPrice;
         $weight -= $model->initial_weight;
-        return (ceil($weight/$model->additional_weight)*$additionalPrice)+$initPrice;
+        $money = (ceil($weight/$model->additional_weight)*$additionalPrice)+$initPrice;
+        $taxFee = $model->tax_rate_id && $model->taxRate ? $money*($model->taxRate->value/100) : null;
+        return array($money,$taxFee);
     }
 }

+ 8 - 6
app/Services/OwnerPriceLogisticService.php

@@ -192,7 +192,6 @@ class OwnerPriceLogisticService
     }
 
     /**
-     * CODE: -1:未找到计费模型
      *
      * @param double $amount
      * @param integer $owner_id
@@ -200,7 +199,7 @@ class OwnerPriceLogisticService
      * @param integer $unit_id
      * @param integer $province_id
      * @param integer $city_id
-     * @return double
+     * @return array
      */
     public function matching($amount, $owner_id, $logistic_id, $unit_id, $province_id, $city_id)
     {
@@ -219,18 +218,21 @@ class OwnerPriceLogisticService
         })->where(function(Builder $query){
             $query->whereNull("operation")->orWhere("operation","");
         })->first();
-        if (!$model || !$model->details)return -1;
+        if (!$model || !$model->details)return array(null,null);
+        $money = null;
         $fee = $model->pick_up_price + $model->fuel_price + $model->service_price; //服务费
         foreach ($model->details as $detail){
             if ($unit_id != $detail->unit_id)continue;
             $arr = explode("-",$detail->range);
             if (count($arr) < 2 || !$arr[1]){
-                if ($amount >= $arr[0])return $this->calculation($amount,$detail,$fee);
+                if ($amount >= $arr[0])$money = $this->calculation($amount,$detail,$fee);
             }else{
-                if ($amount >= $arr[0] && $amount < $arr[1])return $this->calculation($amount,$detail,$fee);
+                if ($amount >= $arr[0] && $amount < $arr[1])$money = $this->calculation($amount,$detail,$fee);
             }
+            if ($money)break;
         }
-        return -1;
+        $taxFee = $model->tax_rate_id && $model->taxRate ? $money*($model->taxRate->value/100) : null;
+        return array($money,$taxFee);
     }
 
     private function calculation($amount, $detail, $fee)

+ 20 - 7
app/Services/OwnerPriceOperationService.php

@@ -310,12 +310,20 @@ class OwnerPriceOperationService
      *      不严格区分入库出库差异 统一模型
      * 七. 2021-03-30 zzd
      *      增加一级二级特征,零头价,满减按总件,附加费用等
+     * 八. 2021-04-19 zzd
+     *      增加税率计算,改变返回值数据结构,增加封顶费
      */
     public function matching($matchObject, $columnMapping, $ownerId, $type = '出库', $typeMark = null)
     {
         $units = app("UnitService")->getUnitMapping(["件","箱"]); //获取单位映射集
         $rules = $this->getOwnerPriceOperation($ownerId,$type,$typeMark);//货主下的全部规则
         if (!$rules)return -2;  //规则不存在跳出
+
+        //建立一组返回变量
+        $id = null;
+        $money = 0;
+        $taxFee = null;
+
         if ($type == '出库')$total = app("OrderService")->getOrderQuantity($ownerId);//获取该货主本月C端单量
         else {
             $total = 0;
@@ -330,17 +338,22 @@ class OwnerPriceOperationService
 
             if ($rule->strategy == '特征'){
                 if (app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject)){
-                    if ($rule->total_price)return ["id"=>$rule->id,"money"=>$result ? explode(",",$rule->total_discount_price)[key($result)] : $rule->total_price];//按单计价存在,直接返回单总价或减免总价
-                    $money = $this->matchItem($rule,$columnMapping,$matchObject,$units,$ownerId,$result);
-                    if ($money>0)return ["id"=>$rule->id,"money"=>$rule->max_fee&&$money>$rule->max_fee ? $rule->max_fee : $money];
+                    if (!$rule->total_price)$money = $this->matchItem($rule,$columnMapping,$matchObject,$units,$ownerId,$result);
+                    $id = $rule->id;
                 };
             }else{
-                if ($rule->total_price)return ["id"=>$rule->id,"money"=>$result ? explode(",",$rule->total_discount_price)[key($result)] : $rule->total_price]; //按单计价存在,直接返回单总价或减免总价
-                $money = $this->matchItem($rule,$columnMapping,$matchObject,$units,$ownerId,$result);
-                if ($money>0)return ["id"=>$rule->id,"money"=>$rule->max_fee&&$money>$rule->max_fee ? $rule->max_fee : $money];
+                if (!$rule->total_price)$money = $this->matchItem($rule,$columnMapping,$matchObject,$units,$ownerId,$result);
+                $id = $rule->id;
             };
+            if ($id){
+                if ($rule->total_price)$money = $result ? explode(",",$rule->total_discount_price)[key($result)] : $rule->total_price;//按单计价存在,直接返回单总价或减免总价
+                $money = $rule->max_fee&&$money>$rule->max_fee ? $rule->max_fee : $money;//封顶费
+                if ($money<=0)$money=null;//计算失误
+                if ($rule->tax_rate_id && $rule->taxRate)$taxFee = $money*($rule->taxRate->value/100);
+                break;
+            }
         }
-        return $money ?? -7;
+        return array($id,$money,$taxFee);
     }
     /**
      * 根据货主 sku寻找箱规并将指定数量切换为箱 返回箱规

+ 6 - 5
app/Services/RejectedBillService.php

@@ -352,22 +352,23 @@ class RejectedBillService
         foreach (Store::query()->with("storeItems")->whereIn("id",$number)->get() as $store){
             /** @var OwnerPriceOperationService $service */
             $service = app("OwnerPriceOperationService");
-            $result = $service->matching($store, Feature::MAPPING["store"], $store->owner_id, "入库",0);
+            list($id,$money,$taxFee) = $service->matching($store, Feature::MAPPING["store"], $store->owner_id, "入库",0);
             $bill = OwnerFeeDetail::query()->where("outer_id",$store->id)->where("outer_table_name","stores")->first();
             if ($bill) $bill->update([
-                    "work_fee" => is_array($result) ? ($result["money"]>0 ? $result["money"] : null) : null,
-                    "owner_price_operation_id" => is_array($result) ? $result["id"] : null,
+                    "work_fee" => $money,
+                    "owner_price_operation_id" => $id,
             ]); else app("OwnerFeeDetailService")->create([
                 "owner_id" => $store->owner_id,
                 "worked_at" => $store->created_at,
                 "type" => "收货",
                 "operation_bill" => $store->asn_code,
                 "commodity_amount" => array_sum(array_column($store->storeItems->toArray(), "amount")),
-                "work_fee" => is_array($result) ? ($result["money"]>0 ? $result["money"] : null) : null,
-                "owner_price_operation_id" => is_array($result) ? $result["id"] : null,
+                "work_fee" => $money,
+                "owner_price_operation_id" => $id,
                 "created_at" => date('Y-m-d H:i:s'),
                 "outer_id" => $store->id,
                 "outer_table_name" => "stores",
+                "work_tax_fee" => $taxFee,
             ]);
         }
     }

+ 4 - 3
app/Services/StoreService.php

@@ -328,7 +328,7 @@ class StoreService
         /** @var OwnerPriceOperationService $service */
         $service = app("OwnerPriceOperationService");
 
-        $result = $service->matching($store, Feature::MAPPING["store"], $store->owner_id, "入库");
+        list($id,$money,$taxFee) = $service->matching($store, Feature::MAPPING["store"], $store->owner_id, "入库");
 
         if (app("OwnerFeeDetailService")->create([
             "owner_id" => $store->owner_id,
@@ -336,11 +336,12 @@ class StoreService
             "type" => "收货",
             "operation_bill" => $store->asn_code,
             "commodity_amount" => array_sum(array_column($store->storeItems->toArray(), "amount")),
-            "work_fee" => is_array($result) ? ($result["money"]>0 ? $result["money"] : null) : null,
-            "owner_price_operation_id" => is_array($result) ? $result["id"] : null,
+            "work_fee" => $money,
+            "owner_price_operation_id" => $id,
             "created_at" => date('Y-m-d H:i:s'),
             "outer_id" => $store->id,
             "outer_table_name" => "stores",
+            "work_tax_fee" => $taxFee,
         ])){
             $amount = 0;
             if ($store->storeItems)foreach ($store->storeItems as $item)$amount += $item->amount;

+ 4 - 3
app/Services/WaybillService.php

@@ -189,13 +189,13 @@ class WaybillService
         if ($waybill->type == "专线"){
             /** @var OwnerPriceLogisticService $service */
             $service = app("OwnerPriceLogisticService");
-            $fee = $service->matching($waybill->carrier_weight_other,$owner_id,$waybill->logistic_id,
+            list($fee,$taxFee) = $service->matching($waybill->carrier_weight_other,$owner_id,$waybill->logistic_id,
                 $waybill->carrier_weight_unit_id_other,$waybill->order ? app("RegionService")->getProvince($waybill->order->province) : $waybill->destinationCity->province_id,
                 $waybill->destination_city_id);
         }else{
             /** @var OwnerPriceDirectLogisticService $service */
             $service = app("OwnerPriceDirectLogisticService");
-            $fee = $service->matching($waybill->mileage,$owner_id,$waybill->carType_id);
+            list($fee,$taxFee) = $service->matching($waybill->mileage,$owner_id,$waybill->carType_id);
         }
 
         $obj = [
@@ -210,9 +210,10 @@ class WaybillService
             "volume" =>$waybill->carrier_weight ?? $waybill->warehouse_weight,
             "weight" => $waybill->carrier_weight_other ?? $waybill->warehouse_weight_other,
             "logistic_id" => $waybill->logistic_id,
-            "logistic_fee" => $fee ?? null,
+            "logistic_fee" => $fee,
             "outer_id" => $waybill->id,
             "outer_table_name" => "waybills",
+            "logistic_tax_fee" => $taxFee,
         ];
         if ($detail)app("OwnerFeeDetailService")->updateFind($detail,$obj);
         else OwnerFeeDetail::query()->create($obj);

+ 13 - 6
app/Services/common/QueryService.php

@@ -77,14 +77,21 @@ class QueryService
         return $query;
     }
 
-    public function priceModelAuditOrRecoverQuery($isAudit, Builder $query, $ownerId, $ids)
+    public function priceModelAuditOrRecoverQuery($isAudit, Builder $query, $ownerId, $ids, $notRelation = false)
     {
         $query = $query->whereNotNull("operation")->where("operation","!=","");
-        if ($ownerId) $query->whereHas("owners",function ($query)use($ownerId){
-            /** @var Builder $query */
-            if (is_array($ownerId))$query->whereIn("id",$ownerId);
-            else $query->where("id",$ownerId);
-        });
+        if ($ownerId){
+            if ($notRelation){
+                if (is_array($ownerId))$query->whereIn("id",$ownerId);
+                else $query->where("id",$ownerId);
+            }else{
+                $query->whereHas("owners",function ($query)use($ownerId){
+                    /** @var Builder $query */
+                    if (is_array($ownerId))$query->whereIn("id",$ownerId);
+                    else $query->where("id",$ownerId);
+                });
+            }
+        }
         if ($ids){
             if (is_array($ids))$query->whereIn("id",$ids);
             else $query->where("id",$ids);

+ 1 - 1
config/api.php

@@ -47,7 +47,7 @@ return [
         'storage'=>[
 //            'relocate' => "http://59.37.126.227:65448/api/haiqEss/gr/relocate",
             'moveBin' => "http://58.33.243.164:2011/api/haiqEss/gr/relocate",  //移动料箱
-            'light' => "http://58.33.243.164:2011/api/haiqEss/ctlPTL",  //控灯
+            'light' => "http://58.33.243.164:40000/api/haiqEss/ctlPTL",  //控灯
         ],
     ],
 

+ 76 - 0
database/migrations/2021_04_16_151135_create_owner_price_systems_table.php

@@ -0,0 +1,76 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateOwnerPriceSystemsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('owner_price_systems', function (Blueprint $table) {
+            $table->id();
+            $table->bigInteger("owner_id")->index()->comment("货主");
+            $table->decimal("usage_fee",9,3)->default(0)->comment("使用费");
+            $table->char("operation",1)->index()->nullable()->comment("操作类型");
+            $table->bigInteger("target_id")->index()->nullable()->comment("目标ID");
+            $table->bigInteger("tax_rate_id")->nullable()->comment("税率");
+            $table->timestamps();
+        });
+        \App\Authority::query()->firstOrCreate(["name"=>"计费模型-系统-录入"],["name"=>"计费模型-系统-录入","alias_name"=>"计费模型-系统-录入"]);
+        Schema::table("logistics",function (Blueprint $table){
+            $table->char("is_bunched")->default("N")->comment("是否子母件");
+        });
+        $tables = ["owner_storage_price_models","owner_price_operations","owner_price_logistics","owner_price_expresses","owner_price_direct_logistics"];
+        foreach ($tables as $t){
+            Schema::table($t, function (Blueprint $table) {
+                $table->bigInteger("tax_rate_id")->nullable()->comment("税率");
+            });
+        }
+        Schema::table("owner_fee_details", function (Blueprint $table) {
+            $table->decimal("work_tax_fee",9,3)->nullable()->comment("作业税费");
+            $table->decimal("logistic_tax_fee",9,3)->nullable()->comment("物流税费");
+        });
+        Schema::table("owner_bill_reports", function (Blueprint $table) {
+            $table->decimal("other_fee",9,3)->nullable()->comment("其他费用");
+        });
+        Schema::table("owner_fee_detail_logistics", function (Blueprint $table) {
+            $table->decimal("tax_fee",9,3)->nullable()->comment("物流税费");
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('owner_price_systems');
+        \App\Authority::query()->where("alias_name","计费模型-系统-录入")->delete();
+        Schema::table("logistics",function (Blueprint $table){
+            $table->dropColumn("is_bunched");
+        });
+        $tables = ["owner_storage_price_models","owner_price_operations","owner_price_logistics","owner_price_expresses","owner_price_direct_logistics"];
+        foreach ($tables as $t){
+            Schema::table($t, function (Blueprint $table) {
+                $table->dropColumn("tax_rate_id");
+            });
+        }
+        Schema::table("owner_fee_details", function (Blueprint $table) {
+            $table->dropColumn("work_tax_fee");
+            $table->dropColumn("logistic_tax_fee");
+        });
+        Schema::table("owner_bill_reports", function (Blueprint $table) {
+            $table->dropColumn("other_fee");
+        });
+        Schema::table("owner_fee_detail_logistics", function (Blueprint $table) {
+            $table->dropColumn("tax_fee");
+        });
+    }
+}

+ 9 - 4
resources/js/queryForm/header.js

@@ -22,6 +22,7 @@ window.Header = function getHeader(object) {
     let settingInfo = localStorage.getItem("settingInfo") ? JSON.parse(localStorage.getItem("settingInfo")) : {
         isCopyWrap : true
     };
+    let keyCode = false;
     let settingCheck = true;
 
     function getTargetChildNode(dom) { //递归获取input子节点
@@ -592,11 +593,15 @@ window.Header = function getHeader(object) {
         _createSetting2();
     }
     function bindGlobalEvent() {
-        document.oncopy = () => {
-            if (settingInfo.isCopyNoWrap){
-                event.preventDefault();
+        document.onkeydown = (e) => {
+            if (e.ctrlKey && e.keyCode===67)keyCode = true;
+        };
+        document.oncopy = (e)=>{
+            if (keyCode && settingInfo.isCopyNoWrap){
+                e.preventDefault();
                 let content = window.getSelection().toString();
-                event.clipboardData.setData("text", content.replace(/[\n\r]/g,' '));
+                e.clipboardData.setData("text", content.replace(/[\n\r]/g,' '));
+                keyCode = false;
             }
         };
     }

+ 76 - 10
resources/views/customer/project/create.blade.php

@@ -165,6 +165,9 @@
                     directLogistic:{
                         items:[],
                     },
+                    system:{
+                        usage_fee:""
+                    },
                 },
                 pool:{//基础数据选择池,以方便异步懒加载而非即时加载 例:units,owners等
                     counting_type:[
@@ -186,6 +189,7 @@
                     express:[],
                     logistic:[],
                     directLogistic:{},
+                    system:{},
                 },
                 thisOperationItemIndex:-1,//当前选中的作业费子项下标,用以唤起特征模态框
                 operationItems:{},//控制作业费子项的渐入展开
@@ -213,7 +217,7 @@
                 this._resetOperation();
                 this.ownerTemp = JSON.parse(JSON.stringify(this.owner));
                 if (type){
-                    this.base = "three";
+                    this.switchBase("three");
                     this.type = "";
                     setTimeout(()=>{
                         this.switchType(type);
@@ -266,9 +270,14 @@
                 switchBase(base){
                     if (!this.owner.id)return;
                     if (base === this.base)return;
-                    if (base === 'three') this._loadStorage();
-                    if (base === 'two')this._getTaxRates();
-                    this.base = base;
+                    if (base === 'three'){
+                        if (!this.pool.taxRates) this._getTaxRates();
+                        this._loadStorage();
+                    }
+                    if (base === 'two')if (!this.pool.taxRates) this._getTaxRates();
+                    setTimeout(()=>{
+                        this.base = base;
+                    },300);
                 },
                 //切换类型
                 switchType(type){
@@ -298,6 +307,10 @@
                             this._loadDirectLogistic();
                             dom = $("#directLogistic-card");
                             break;
+                        case "system":
+                            dom = $("#system-card");
+                            if(this.selectedModel.system)this.model.system = this.selectedModel.system;
+                            break;
                     }
                     dom.addClass("animation-translation");
                     dom.fadeOut(500);
@@ -317,8 +330,9 @@
                             });
                             break;
                         case "two":
-                            if (this._verifyTwo())this.base = "three";
-                            this._loadStorage();
+                            if (this._verifyTwo()){
+                                this.switchBase('three');
+                            }
                             break;
                     }
                 },
@@ -487,6 +501,7 @@
                         if (res.express_audit_count)audit.express = true;
                         if (res.logistic_audit_count)audit.logistic = true;
                         if (res.direct_logistic_audit_count)audit.directLogistic = true;
+                        if (res.system_audit_count)audit.system = true;
                         this.audit = audit;
                         if (res.owner_storage_price_models.length>0)this.selectedModel.storage = res.owner_storage_price_models;
                         if (res.owner_price_operations.length>0){
@@ -516,6 +531,7 @@
                             this.upList["directLogistic-item"] = true;
                             this.selectedModel.directLogistic = this._overrideDirectLogistic(res.owner_price_direct_logistics[0]);
                         }
+                        if (res.owner_price_system)this.selectedModel.system = res.owner_price_system;
                         setTimeout(()=> {
                             $(".up").slideUp();
                             this.isLoad = true;
@@ -553,11 +569,11 @@
                     if (!this.pool.owners)this._getOwners();
                     if (!this.pool.logistics)this._getLogistics();
                 },
-                _setModelData(key,val){
+                _setModelData(key,val,column='name',append=""){
                     if (!val)return;
                     let mapping = [];
                     val.forEach(item=>{
-                        mapping[item.id] = item.name;
+                        mapping[item.id] = item[column]+append;
                     });
                     this.$set(this.pool,key,val);
                     this.$set(this.poolMapping,key,mapping);
@@ -589,7 +605,7 @@
                         this._setModelData("logistics",res);
                         setTimeout(()=>{
                             $(".selectpicker").selectpicker('refresh');
-                        },0);
+                        },100);
                     });
                 },
                 //获取车型
@@ -600,7 +616,7 @@
                 //获取税率
                 _getTaxRates(){
                     let url = "{{url('maintenance/taxRate/get')}}";
-                    window.axios.post(url).then(res=>{this._setModelData("taxRates",res.data);});
+                    window.axios.post(url).then(res=>{this._setModelData("taxRates",res.data,"value","%");});
                 },
                 //保存模型
                 saveModel(){
@@ -621,8 +637,32 @@
                         case "directLogistic":
                             this._verifyDirectLogistic();
                             break;
+                        case "system":
+                            this._verifySystem();
+                            break;
                     }
                 },
+                _verifySystem(){
+                    if (this.model.system.usage_fee<0){
+                        this.errors = {usage_fee:["费用不得小于0"]};
+                        return;
+                    }
+                    let url = "{{url('maintenance/priceModel/apiStoreSystem')}}";
+                    let params = this.model.system;
+                    params.owner_id = this.ownerTemp.id;
+                    window.tempTip.postBasicRequest(url,params,res=>{
+                        if (res && res.errors){
+                            this.errors = res.errors;
+                            return;
+                        }
+                        this.selectedModel.system = res;
+                        this.model.system = {
+                            usage_fee:"",
+                        };
+                        this.errors = {};
+                        this.audit.system = true;
+                    });
+                },
                 _verifyStorage(){
                     let error = {};
                     if (!this.model.storage.counting_type)error["counting_type"] = ["未选择计费类型"];
@@ -1362,6 +1402,9 @@
                         case "logistic":
                             this._getLogisticPriceModel();
                             break;
+                        case "system":
+                            this._getSystemPriceModel();
+                            break;
                         default:
                             this._getDirectLogisticPriceModel();
                     }
@@ -1453,6 +1496,11 @@
                         this.isSearch = false;
                     });
                 },
+                _getSystemPriceModel(){
+                    this.searchResult = [];
+                    this.searchResultMapping = [];
+                    this.isSearch = false;
+                },
                 _getLogisticPriceModel(){
                     let url = "{{url('maintenance/priceModel/apiGetLogistic')}}";
                     window.tempTip.postBasicRequest(url,this.introduce,res=>{
@@ -1648,6 +1696,16 @@
                         });
                     });
                 },
+                //删除系统
+                deleteSystem(item){
+                    window.tempTip.confirm("您确定要删除该系统计费吗?",()=>{
+                        window.tempTip.postBasicRequest("{{url('maintenance/priceModel/apiDelSystem')}}",{id:item.id},res=>{
+                            this.$set(this.selectedModel,"system",{usage_fee:""});
+                            this.audit.system = true;
+                            return "删除成功";
+                        });
+                    });
+                },
                 //编辑仓储
                 editStorage(index){
                     this.switchType("storage");
@@ -1679,6 +1737,11 @@
                     this.switchType("directLogistic");
                     this.model.directLogistic = JSON.parse(JSON.stringify(this.selectedModel.directLogistic));
                 },
+                //编辑系统
+                editSystem(){
+                    this.switchType("system");
+                    this.model.system = JSON.parse(JSON.stringify(this.selectedModel.system));
+                },
                 //搜索快递子项
                 searchExpress(e){
                     let val = e.target.value;
@@ -1775,6 +1838,9 @@
                                     this.upList["directLogistic-item"] = true;
                                     this.selectedModel.directLogistic = this._overrideDirectLogistic(res[0]);
                                     break;
+                                case "system":
+                                    this.selectedModel.system = res;
+                                    break;
                             }
                             this.$set(this.audit,type,false);
                         })

+ 3 - 2
resources/views/customer/project/index.blade.php

@@ -66,7 +66,7 @@
                     <td><span>@{{ owner.customer_name }}</span></td>
                     <td><span>@{{ owner.user_owner_group_name }}</span></td>
                     <td><span>@{{ owner.user_work_group_name }}</span></td>
-                    <td><span><b>@{{owner.relevance ? owner.relevance.length : 0}}</b>/5&nbsp;<span class="badge badge-success" v-if="owner.audit_count>0">@{{ owner.audit_count }}项待审</span></span></td>
+                    <td><span><b>@{{owner.relevance ? owner.relevance.length : 0}}</b>/6&nbsp;<span class="badge badge-success" v-if="owner.audit_count>0">@{{ owner.audit_count }}项待审</span></span></td>
                     <td><span>@{{ owner.created_at }}</span></td>
                     <td><span>@{{ owner.customer_company_name }}</span></td>
                     <td><span>@{{ ownerSubjection[owner.subjection] }}</span></td>
@@ -108,7 +108,8 @@
                         user_work_group_name:"{{$owner->userWorkGroup ? $owner->userWorkGroup->name : ''}}",
                         is_activation : "{{$owner->deleted_at ? '否' : '是'}}",
                         ownerStoragePriceModels : {!! $owner->ownerStoragePriceModels !!},
-                        audit_count:"{{count($owner->storageAudit)+count($owner->operationAudit)+count($owner->expressAudit)+count($owner->logisticAudit)+count($owner->directLogisticAudit)}}",
+                        audit_count:"{{count($owner->storageAudit)+count($owner->operationAudit)+count($owner->expressAudit)+count($owner->logisticAudit)+count($owner->directLogisticAudit)+($owner->systemAudit ? 1 : 0)}}",
+                        a:"{{$owner}}"
                     },
                     @endforeach
                 ],

+ 6 - 0
resources/views/customer/project/part/_directLogistic.blade.php

@@ -14,6 +14,12 @@
         <strong>@{{ errors.base_km[0] }}</strong>
     </span>
 </div>
+<div class="row mt-3">
+    <label for="tax_rate_id" class="col-3 text-muted">税率</label>
+    <select id="tax_rate_id" class="col-3 form-control ml-3" v-model="model.directLogistic.tax_rate_id">
+        <option v-for="tax in pool.taxRates" :value="tax.id">@{{ tax.value }}%</option>
+    </select>
+</div>
 <div class="row mt-3">
     <label class="col-3 cursor-pointer" @click="show('directLogistic-item-card')"><span @click="show('directLogistic-item-card')">详情&nbsp;
         <span class="fa" :class="upList['express-item'] ? 'fa-angle-double-right' : 'fa-angle-double-down'"></span></span></label>

+ 7 - 1
resources/views/customer/project/part/_express.blade.php

@@ -21,7 +21,13 @@
            v-model="model.express.additional_weight" :class="errors.additional_weight ? 'is-invalid' : ''"></label>
 </div>
 <div class="row mt-3">
-    <label for="isInterval" class="col-3"><b class="text-danger">* </b>设定区间</label>
+    <label for="tax_rate_id" class="col-3 text-muted">税率</label>
+    <select id="tax_rate_id" class="col-3 form-control ml-3" v-model="model.express.tax_rate_id">
+        <option v-for="tax in pool.taxRates" :value="tax.id">@{{ tax.value }}%</option>
+    </select>
+</div>
+<div class="row mt-3">
+    <label for="isInterval" class="col-3">设定区间</label>
     <label class="col-7"><input id="isInterval" type="checkbox" class="switch"  v-model="model.express.isInterval"></label>
 </div>
 <div class="row mt-3" v-if="model.express.isInterval">

+ 7 - 1
resources/views/customer/project/part/_logistic.blade.php

@@ -58,7 +58,7 @@
         <option v-for="unit in pool.units" :value="unit.id">@{{ unit.name }}</option>
     </select>
     <label for="logistic_other_unit_range" class="col-2 text-right"><b class="text-danger">*</b>区间值</label>
-    <input id="logistic_other_unit_range" type="text" placeholder="文字描述区间逗号(,)间隔,示例:0-5,10-30,30-"
+    <input id="logistic_other_unit_range" type="text" placeholder="文字描述区间逗号(,)间隔,示例:0-5,5-30,30-" title="文字描述区间逗号(,)间隔,示例:0-5,5-30,30-"
            v-model="model.logistic.other_unit_range" class="col-3 form-control" :class="errors.other_unit_range ? 'is-invalid' : ''" @change="changeRange('other_ranges')">
 </div>
 <div class="row mt-0">
@@ -72,4 +72,10 @@
             <button type="button" class="btn btn-sm btn-outline-info col-4" @click="showDetailModal()">详情列表</button>
         </div>
     </div>
+</div>
+<div class="row mt-3">
+    <label for="tax_rate_id" class="col-2 text-muted">税率</label>
+    <select id="tax_rate_id" class="col-3 form-control" v-model="model.logistic.tax_rate_id">
+        <option v-for="tax in pool.taxRates" :value="tax.id">@{{ tax.value }}%</option>
+    </select>
 </div>

+ 6 - 0
resources/views/customer/project/part/_operation.blade.php

@@ -181,4 +181,10 @@
 <div class="row mt-3">
     <label for="remark" class="col-2">备注</label>
     <textarea id="remark" class="col-6 form-control" v-model="model.operation.remark"></textarea>
+</div>
+<div class="row mt-3">
+    <label for="tax_rate_id" class="col-2 text-muted">税率</label>
+    <select id="tax_rate_id" class="col-3 form-control" v-model="model.operation.tax_rate_id">
+        <option v-for="tax in pool.taxRates" :value="tax.id">@{{ tax.value }}%</option>
+    </select>
 </div>

+ 6 - 0
resources/views/customer/project/part/_storage.blade.php

@@ -123,4 +123,10 @@
     <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.discount_value">
         <strong>@{{ errors.discount_value[0] }}</strong>
     </span>
+</div>
+<div class="row mt-3">
+    <label for="tax_rate_id" class="col-2 text-muted">税率</label>
+    <select id="tax_rate_id" class="col-3 form-control" v-model="model.storage.tax_rate_id">
+        <option v-for="tax in pool.taxRates" :value="tax.id">@{{ tax.value }}%</option>
+    </select>
 </div>

+ 13 - 0
resources/views/customer/project/part/_system.blade.php

@@ -0,0 +1,13 @@
+<div class="row">
+    <label for="usage_fee" class="col-2 text-info">系统使用费</label>
+    <input id="usage_fee" type="number" step="0.01" min="0" :class="errors.usage_fee ? 'is-invalid' : ''" class="col-6 form-control" v-model="model.system.usage_fee">
+    <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.usage_fee">
+        <strong>@{{ errors.usage_fee[0] }}</strong>
+    </span>
+</div>
+<div class="row mt-3">
+    <label for="tax_rate_id" class="col-2 text-muted">税率</label>
+    <select id="tax_rate_id" class="col-3 form-control" v-model="model.system.tax_rate_id">
+        <option v-for="tax in pool.taxRates" :value="tax.id">@{{ tax.value }}%</option>
+    </select>
+</div>

+ 37 - 2
resources/views/customer/project/part/_three.blade.php

@@ -23,6 +23,7 @@
                         <th>计时单位</th>
                         <th>减免类型</th>
                         <th>减免值</th>
+                        <th>税率</th>
                         <th></th>
                     </tr>
                     <tr v-for="(item,i) in selectedModel.storage" style="cursor: pointer" @dblclick="editStorage(i)">
@@ -43,6 +44,7 @@
                         <td>@{{ poolMapping.units ? poolMapping.units[item.time_unit_id] : '' }}</td>
                         <td>@{{ item.discount_type }}</td>
                         <td>@{{ item.discount_value }}</td>
+                        <td>@{{ poolMapping.taxRates ? poolMapping.taxRates[item.tax_rate_id] : '' }}</td>
                         <td class="cursor-pointer" @click.stop="delStorage(item,i)"><span class="font-weight-bold text-danger">&times;</span></td>
                     </tr>
                 </table>
@@ -76,6 +78,7 @@
                                     <label>@{{ operation.name }}</label><span class="badge badge-pill badge-danger" v-if="operation.isRejected">退</span>
                                     <label v-if="operation.remark" class="text-secondary">&nbsp;&nbsp;(@{{ operation.remark }})</label>
                                     <label v-if="operation.surcharge">耗材附加费:<b>@{{ operation.surcharge }}</b>/@{{ poolMapping.units ? poolMapping.units[operation.surcharge_unit_id] : '' }}</label>
+                                    <label v-if="operation.tax_rate_id">税率:@{{ poolMapping.taxRates ? poolMapping.taxRates[operation.tax_rate_id] : '' }}</label>
                                 </div>
                                 <div class="col-1">
                                     <span class="cursor-pointer text-danger font-weight-bold"
@@ -123,6 +126,7 @@
                                     <label>@{{ operation.name }}</label>
                                     <label v-if="operation.remark" class="text-secondary">&nbsp;&nbsp;(@{{ operation.remark }})</label>
                                     <label v-if="operation.surcharge">耗材附加费:<b>@{{ operation.surcharge }}</b>/@{{ poolMapping.units ? poolMapping.units[operation.surcharge_unit_id] : '' }}</label>
+                                    <label v-if="operation.tax_rate_id">税率:@{{ poolMapping.taxRates ? poolMapping.taxRates[operation.tax_rate_id] : '' }}</label>
                                 </div>
                                 <div class="col-1">
                                     <span class="cursor-pointer text-danger font-weight-bold"
@@ -186,6 +190,7 @@
                         <th>名称</th>
                         <th>首重值(KG)</th>
                         <th>续重值(KG)</th>
+                        <th>税率</th>
                         <th>详情</th>
                         <th></th>
                     </tr>
@@ -193,12 +198,13 @@
                         <tr>
                             <td>
                                 <div class="text-overflow-warp-100 small">
-                                    <label v-for="(logistic,j) in express.logistics" class="m-0">@{{ poolMapping.logistics ? poolMapping.logistics[logistic] : '' }}</label>
+                                    <label v-for="(logistic,j) in express.logistics" class="m-0">@{{ poolMapping.logistics ? poolMapping.logistics[logistic] : '' }}<br></label>
                                 </div>
                             </td>
                             <td>@{{ express.name }}</td>
                             <td>@{{ express.initial_weight }}</td>
                             <td>@{{ express.additional_weight }}</td>
+                            <td>@{{ poolMapping.taxRates ? poolMapping.taxRates[express.tax_rate_id] : '' }}</td>
                             <td @click.stop="show('express-item-'+i)" class="cursor-pointer">
                                 <span class="fa" :class="upList['express-item-'+i] ? 'fa-angle-double-right' : 'fa-angle-double-down'"></span>
                                 &nbsp;@{{ express.items.length }} 省份</td>
@@ -284,6 +290,7 @@
                         <th>提货费</th>
                         <th>燃油附加费</th>
                         <th>信息服务费</th>
+                        <th>税率</th>
                         <th>详情</th>
                         <th></th>
                     </tr>
@@ -302,6 +309,7 @@
                             <td>@{{ logistic.pick_up_price }}</td>
                             <td>@{{ logistic.fuel_price }}</td>
                             <td>@{{ logistic.service_price }}</td>
+                            <td>@{{ poolMapping.taxRates ? poolMapping.taxRates[logistic.tax_rate_id] : '' }}</td>
                             <td @click.stop="show('logistic-item-'+i)" class="cursor-pointer">
                                 <span class="fa" :class="upList['logistic-item-'+i] ? 'fa-angle-double-right' : 'fa-angle-double-down'"></span>
                                 &nbsp;@{{ logistic.items.length }} 地区
@@ -363,7 +371,8 @@
                 <div class="row">
                     <span class="col-4">名称:<b>@{{ selectedModel.directLogistic.name }}</b></span>
                     <span class="col-4">起步数(KM):<b>@{{ selectedModel.directLogistic.base_km }}</b></span>
-                    <span class="col-1 offset-3" v-if="selectedModel.directLogistic.name">
+                    <span class="col-3">税率:<b>@{{ poolMapping.taxRates ? poolMapping.taxRates[selectedModel.directLogistic.tax_rate_id] : '' }}</b></span>
+                    <span class="col-1" v-if="selectedModel.directLogistic.name">
                         <span class="cursor-pointer text-danger font-weight-bold" @click.stop="delDirectLogistic(selectedModel.directLogistic)">&times;</span>
                     </span>
                 </div>
@@ -391,6 +400,28 @@
                 </div>
             </div>
         </div>
+        <div class="card" id="system-card">
+            <div class="card-header bg-light-info row">
+                <div class="col-3 pull-left font-weight-bold cursor-pointer text-secondary" @click="show('system')"><span class="fa fa-align-justify"></span>&nbsp;系统</div>
+                <div class="col-6 text-center">
+                    <div v-if="audit.system">
+                        @can("项目管理-项目-计费模型-审核")<button class="btn btn-sm btn-success" type="button" @click="auditOrRecoverModel('system')">审核</button>
+                        <button class="btn btn-sm btn-danger" type="button" @click="auditOrRecoverModel('system',false)">恢复</button>@endcan
+                    </div>
+                </div>
+                <div class="col-3 pull-right small mb-0 text-secondary" v-if="selectedModel.system.id">双击下方已添加内容可编辑</div>
+            </div>
+            <div class="card-body" id="system" @dblclick="editSystem()" style="cursor: pointer">
+                <div class="row">
+                    <label class="col-3">系统使用费:</label>
+                    <label class="col-9">@{{ selectedModel.system.usage_fee }}</label>
+                </div>
+                <div class="row">
+                    <label class="col-3">税率:</label>
+                    <label class="col-9">@{{ poolMapping.taxRates ? poolMapping.taxRates[selectedModel.system.tax_rate_id] : '' }}</label>
+                </div>
+            </div>
+        </div>
     </div>
     <div class="col-6">
         <div class="card">
@@ -400,6 +431,7 @@
                 <button type="button" class="btn mr-1" :class="type == 'express' ? 'btn-primary text-white' : 'btn-outline-primary'" @click="switchType('express')">快递</button>
                 <button type="button" class="btn mr-1" :class="type == 'logistic' ? 'btn-primary text-white' : 'btn-outline-primary'" @click="switchType('logistic')">物流</button>
                 <button type="button" class="btn mr-1" :class="type == 'directLogistic' ? 'btn-primary text-white' : 'btn-outline-primary'" @click="switchType('directLogistic')">直发</button>
+                <button type="button" class="btn mr-1" :class="type == 'system' ? 'btn-primary text-white' : 'btn-outline-primary'" @click="switchType('system')">系统</button>
             </div>
             <div class="card-body">
                 @can("计费模型-仓储-录入")<div v-if="type == 'storage'">
@@ -419,6 +451,9 @@
                 @can("计费模型-直发-录入")<div v-show="type == 'directLogistic'">
                     @include("customer.project.part._directLogistic")
                 </div>@endcan
+                @can("计费模型-系统-录入")<div v-show="type == 'system'">
+                    @include("customer.project.part._system")
+                </div>@endcan
                 @include("customer.project.part._introducePriceModel")
                 <div class="row mt-3" v-if="base=='three'">
                     <div class="col-2"></div>

+ 6 - 0
resources/views/maintenance/logistic/create.blade.php

@@ -53,6 +53,12 @@
                             @enderror
                         </div>
                     </div>
+                    <div class="form-group row">
+                        <label for="is_bunched" class="col-2 col-form-label text-right">是否子母单</label>
+                        <div class="col-8">
+                            <input id="is_bunched" name="is_bunched" type="checkbox" class="switch" @if(old('is_bunched')) checked @endif>
+                        </div>
+                    </div>
                     <div class="form-group row">
                         <label for="mobile" class="col-2 col-form-label text-right">承运商电话</label>
                         <div class="col-8">

+ 6 - 0
resources/views/maintenance/logistic/edit.blade.php

@@ -59,6 +59,12 @@
                             @enderror
                         </div>
                     </div>
+                    <div class="form-group row">
+                        <label for="is_bunched" class="col-2 col-form-label text-right">是否子母单</label>
+                        <div class="col-8">
+                            <input id="is_bunched" type="checkbox" name="is_bunched" class="switch" @if(old('is_bunched') ?? $logistic->is_bunched=='Y') checked @endif>
+                        </div>
+                    </div>
                     <div class="form-group row">
                         <label for="mobile" class="col-2 col-form-label text-right">承运商电话</label>
                         <div class="col-8">

+ 2 - 2
resources/views/maintenance/logistic/index.blade.php

@@ -26,7 +26,7 @@
                     </tr>
                     <tr v-for="(logistic,i) in logistics" @click="selectTr===i+1?selectTr=0:selectTr=i+1" :class="selectTr===i+1?'focusing' : ''">
                         <td class="text-muted">@{{logistic.id}}</td>
-                        <td>@{{logistic.name}}</td>
+                        <td>@{{logistic.name}}&nbsp;<span class="badge badge-success" v-if="logistic.is_bunched=='Y'">子母单</span></td>
                         <td>@{{logistic.code}}</td>
                         <td>@{{logistic.mobile}}</td>
                         <td>@{{logistic.type}}</td>
@@ -56,7 +56,7 @@
                     @foreach( $logistics as $logistic )
                     {id:'{{$logistic->id}}',name:'{{$logistic->name}}',code:'{{$logistic->code}}',
                         mobile:"{{$logistic->mobile}}",type:"{{$logistic->type}}",delivery_fee:"{{$logistic->delivery_fee}}",
-                        remark:"{{$logistic->remark}}",created_at:'{{$logistic->created_at}}'},
+                        remark:"{{$logistic->remark}}",created_at:'{{$logistic->created_at}}',is_bunched:"{{$logistic->is_bunched}}"},
                     @endforeach
                 ],
                 selectTr:0

+ 7 - 5
resources/views/package/logistic/index.blade.php

@@ -16,6 +16,7 @@
                     <th>状态</th>
                     <th>快递公司</th>
                     <th>货主</th>
+                    <th>省份</th>
                     <th>发出日期</th>
                     <th>收货日期</th>
                     <th>称重日期</th>
@@ -39,6 +40,7 @@
                     <td>@{{ package.status }}</td>
                     <td>@{{ package.order != null  ? package.order.logistic.name : '#' }}</td>
                     <td>@{{ package.order != null  ? package.order.owner.name : '#' }}</td>
+                    <td>@{{ package.order != null  ? package.order.province : '#' }}</td>
                     <td>@{{ package.sent_at }}</td>
                     <td>@{{ package.received_at }}</td>
                     <td>@{{ package.weighed_at }}</td>
@@ -58,11 +60,11 @@
                             </label>
                         </div>
                     </td>
-                    <td class="text-overflow-warp-200 " v-if="package.order && package.order.issue">@{{ package.order.issue.result_explain }}</td>
-                    <td class="text-overflow-warp-200 " v-if="package.order && package.order.issue && package.order.issue.issue_type">@{{ package.order.issue.issue_type.name }}</td>
-                    <td class="text-overflow-warp-200 " v-if="package.order && package.order.issue && package.order.issue.logs.length >0"><span v-for="log in package.order.issue.logs">@{{ log.content }}<br></span></td>
-                    <td class="text-overflow-warp-200 " v-if="package.order && package.order.issue && package.order.issue.logs.length >0"><span v-for="log in package.order.issue.logs">@{{ log.user.name }}<br></span></td>
-                    <td class="text-overflow-warp-200 " v-if="package.order && package.order.issue && package.order.issue.logs.length >0"><span v-for="log in package.order.issue.logs">@{{ log.created_at }}<br></span></td>
+                    <td class="text-overflow-warp-200"><span v-if="package.order && package.order.issue">@{{ package.order.issue.result_explain }}</span></td>
+                    <td class="text-overflow-warp-200"><span v-if="package.order && package.order.issue && package.order.issue.issue_type">@{{ package.order.issue.issue_type.name }}</span></td>
+                    <td class="text-overflow-warp-200"><span v-if="package.order && package.order.issue && package.order.issue.logs.length >0"><span v-for="log in package.order.issue.logs">@{{ log.content }}<br></span></span> </td>
+                    <td class="text-overflow-warp-200"><span v-if="package.order && package.order.issue && package.order.issue.logs.length >0"><span v-for="log in package.order.issue.logs">@{{ log.user.name }}<br></span></span> </td>
+                    <td class="text-overflow-warp-200"><span v-if="package.order && package.order.issue && package.order.issue.logs.length >0"><span v-for="log in package.order.issue.logs">@{{ log.created_at }}<br></span></span> </td>
                 </tr>
             </table>
             <div class="text-info h5 btn btn">{{$orderPackages->count()}}/{{$orderPackages->total()}}</div>

+ 32 - 3
resources/views/rejected/create.blade.php

@@ -430,7 +430,9 @@
                         @foreach($qualityLabels as $qualityLabel)
                     {id:'{{$qualityLabel->id}}',name:'{{$qualityLabel->name}}'},
                     @endforeach
-                ]
+                ],
+                commodityOwnerId:'',
+
             },
             mounted:function () {
                 let _this=this;
@@ -483,8 +485,10 @@
                     axios.post(url,{barcode:barcode}).then(function (response) {
                         _this.cleanError();
                         if(response.data.success==='true'){
-                            if(response.data.name){
-                                _this.itemInputting.name_goods=response.data.name;
+                            if(response.data.commodity){
+                                // _this.itemInputting.name_goods=response.data.name;
+                                 _this.itemInputting.name_goods=response.data.commodity.name;
+                                 _this.commodityOwnerId=response.data.commodity.owner_id;
                             }
                         }else{
                             tempTip.setDuration(3000);
@@ -685,6 +689,9 @@
                     let _this=this;
                     let url='{{url('apiLocal/rejectedBillItem/store')}}';
                     _this.itemInputting.id_rejected_bill=_this.status.editingBill.id;
+                    // if (_this.items.length<1 && _this.commodityOwnerId!==_this.billInputting.id_owner){
+                    //
+                    // }
                     axios.post(url,_this.itemInputting).then(function (response) {
                         _this.cleanError();
                         if(response.data.success==='true'){
@@ -710,6 +717,28 @@
                         alert('连接错误:'+response)
                     });
                 },
+                isChangeOwner(){
+                    window.tempTip.confirm('当前退货记录货主名与录入商品的货主不匹配' + this.procurement_type[type] + ' ' + code, () => {
+                        window.axios.get("{{url('')}}/" + id)
+                            // .then(res => {
+                        //         if (res.data.success) {
+                        //             this.procurements.forEach(function (procurement) {
+                        //                 if (procurement.id === res.data.data.id) {
+                        //                     procurement.status = res.data.data.status;
+                        //                     window.tempTip.setDuration(2000);
+                        //                     window.tempTip.showSuccess("已成功取消该条采购申请");
+                        //                 }
+                        //             })
+                        //         } else {
+                        //             tempTip.setDuration(3000);
+                        //             tempTip.show(res.data.message);
+                        //         }
+                        //     }).catch(err => {
+                        //     window.tempTip.setDuration(3000);
+                        //     window.tempTip.show("网络错误:" + err);
+                        // });
+                    });
+                },
                 endAndPackCommitEdit:function () {
                     let _this=this;
                     if(_this.items.length===0){

+ 193 - 36
resources/views/test.blade.php

@@ -37,40 +37,133 @@
     </tr>
 </table>
 <div class="modal fade" tabindex="-1" role="dialog" id="auditOrRecover">
-    <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
+    <div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
         <div class="modal-content">
             <div class="modal-header">
                 <button type="button" class="close" data-dismiss="modal">&times;</button>
             </div>
             <div class="modal-body">
-                <div v-for="s in auditList.storage" class="row">
-                    <label class="col-3 text-right">@{{ s.name }}</label>
-                    <label class="col-1 h3" style="bottom: 0.25rem">
+                <div class="row">
+                    <label class="col-3 text-right h4"><span class="badge badge-success">新增</span></label>
+                    <label class="col-1 h3 text-success" style="bottom: 0.25rem">
                         <span class="fa fa-long-arrow-right"></span>
                     </label>
-                    <div class="col-8 h4">
-                        <div v-if="s.operation == 'C'" class="row">
-                            <div class="col-2">
-                                <span class="badge badge-success">新增</span>
-                            </div>
-                            <div class="col-10">
-                                <div v-for="(val,key) in s" v-if="key!='name'">
-
-                                </div>
-                            </div>
-                        </div>
-                        <div v-if="s.operation == 'U'" class="row">
-                            <div class="row">
-                                <div class="col-2">
-                                    <span class="badge badge-primary">修改</span>
-                                </div>
-                                <div class="col-10">
-
-                                </div>
-                            </div>
+                    <div class="col-8 border-bottom border-success">
+                        <div v-if="selectedAudit=='storage'" v-for="s in auditList.storage.C">
+                            <div><b>@{{ s.name }}</b><span class="text-muted">(@{{ s.counting_type }}-@{{ s.using_type }})</span></div>
+                        </div>
+                        <div v-if="selectedAudit=='operation'" v-for="s in auditList.operation.C">
+                            <div><b>@{{ s.name }}</b><span class="text-muted">(@{{ s.operation_type }}-@{{ s.strategy }})</span></div>
+                        </div>
+                        <div v-if="selectedAudit=='express'" v-for="s in auditList.express.C">
+                            <div><b>@{{ s.name }}</b></div>
+                        </div>
+                        <div v-if="selectedAudit=='logistic'" v-for="s in auditList.logistic.C">
+                            <div><b>@{{ s.name }}</b></div>
+                        </div>
+                        <div v-if="selectedAudit=='directLogistic'" v-for="s in auditList.directLogistic.C">
+                            <div><b>@{{ s.name }}</b><span class="text-muted">(起步:@{{ s.base_km }}KM)</span></div>
+                        </div>
+                        <div v-if="selectedAudit=='system'" v-for="s in auditList.system.C">
+                            <div>使用费:¥<b>@{{ s.usage_fee }}</b></div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <label class="col-3 text-right h4"><span class="badge badge-danger">删除</span></label>
+                    <label class="col-1 h3 text-danger" style="bottom: 0.25rem">
+                        <span class="fa fa-long-arrow-right"></span>
+                    </label>
+                    <div class="col-8 border-bottom border-danger">
+                        <div v-if="selectedAudit=='storage'" v-for="s in auditList.storage.D">
+                            <table class="table table-sm">
+                                <tr class="text-center">
+                                    <th>名称</th>
+                                    <th>计费类型</th>
+                                    <th>用仓类型</th>
+                                    <th>最低起租面积</th>
+                                    <th>减免类型</th>
+                                    <th>减免值</th>
+                                    <th>单位</th>
+                                    <th>计时单位</th>
+                                    <th>数量-单价</th>
+                                    <th>税率</th>
+                                </tr>
+                                <tr>
+                                    <td>@{{ s.name }}</td>
+                                    <td>@{{ s.counting_type }}</td>
+                                    <td>@{{ s.using_type }}</td>
+                                    <td>@{{ s.minimum_area }}</td>
+                                    <td>@{{ s.discount_type }}</td>
+                                    <td>@{{ s.discount_value }}</td>
+                                    <td>@{{ s.unit_id }}</td>
+                                    <td>@{{ s.time_unit_id }}</td>
+                                    <td>
+                                        <div>
+                                            <div class="float-left">
+                                                <small v-for="(a,i) in s.amount_interval" v-if="i!=s.amount_interval.length-1">@{{ a }}-@{{ s.amount_interval[i+1] }}(@{{ s.price[i] }}元)<br></small>
+                                                <small>@{{ s.amount_interval[s.amount_interval.length-1] }}&nbsp;+<br></small>
+                                            </div>
+                                            <div class="float-left">
+                                                <span class="float-left fa fa-long-arrow-right" style="margin-top: 1em"></span>
+                                                <div class="float-left">
+                                                    <small v-for="(a,i) in s.amount_interval" v-if="i!=s.amount_interval.length-1">@{{ a }}-@{{ s.amount_interval[i+1] }}(@{{ s.price[i] }}元)<br></small>
+                                                    <small>@{{ s.amount_interval[s.amount_interval.length-1] }}&nbsp;+<br></small>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </td>
+                                    <td>@{{ s.tax_rate_id }}%</td>
+                                </tr>
+                            </table>
+                        </div>
+                        <div v-if="selectedAudit=='operation'" v-for="s in auditList.operation.C">
+                            <div><b>@{{ s.name }}</b><span class="text-muted">(@{{ s.operation_type }}-@{{ s.strategy }})</span></div>
+                        </div>
+                        <div v-if="selectedAudit=='express'" v-for="s in auditList.express.C">
+                            <div><b>@{{ s.name }}</b></div>
+                        </div>
+                        <div v-if="selectedAudit=='logistic'" v-for="s in auditList.logistic.C">
+                            <div><b>@{{ s.name }}</b></div>
+                        </div>
+                        <div v-if="selectedAudit=='directLogistic'" v-for="s in auditList.directLogistic.C">
+                            <div><b>@{{ s.name }}</b><span class="text-muted">(起步:@{{ s.base_km }}KM)</span></div>
+                        </div>
+                        <div v-if="selectedAudit=='system'" v-for="s in auditList.system.C">
+                            <div>使用费:<b>@{{ s.usage_fee }}</b></div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row">
+                    <label class="col-3 text-right h4"><span class="badge badge-primary">修改</span></label>
+                    <label class="col-1 h3 text-primary" style="bottom: 0.25rem">
+                        <span class="fa fa-long-arrow-right"></span>
+                    </label>
+                    <div class="col-8">
+                        <div v-if="selectedAudit=='storage'" v-for="s in auditList.storage.U">
+                            <table class="table table-sm">
+                                <tr>
+                                    <th v-for="(key,val) in auditList.mapping.storage">@{{ val }}</th>
+                                </tr>
+                                <tr>
+                                    <td v-for="(key,val) in auditList.mapping.storage" v-html="s[key]"></td>
+                                </tr>
+                            </table>
+                        </div>
+                        <div v-if="selectedAudit=='operation'" v-for="s in auditList.operation.C">
+                            <div><b>@{{ s.name }}</b><span class="text-muted">(@{{ s.operation_type }}-@{{ s.strategy }})</span></div>
                         </div>
-                        <div v-if="s.operation == 'D'" class="row">
-                            <span class="badge badge-danger">删除</span>
+                        <div v-if="selectedAudit=='express'" v-for="s in auditList.express.C">
+                            <div><b>@{{ s.name }}</b></div>
+                        </div>
+                        <div v-if="selectedAudit=='logistic'" v-for="s in auditList.logistic.C">
+                            <div><b>@{{ s.name }}</b></div>
+                        </div>
+                        <div v-if="selectedAudit=='directLogistic'" v-for="s in auditList.directLogistic.C">
+                            <div><b>@{{ s.name }}</b><span class="text-muted">(起步:@{{ s.base_km }}KM)</span></div>
+                        </div>
+                        <div v-if="selectedAudit=='system'" v-for="s in auditList.system.C">
+                            <div>使用费:<b>@{{ s.usage_fee }}</b></div>
                         </div>
                     </div>
                 </div>
@@ -90,19 +183,83 @@
         el:"#auditOrRecover",
         data:{
             auditList:{
-                storage:[
-                    {name:"笕尚退货",operation:"C"},
-                    {name:"笕尚退货",operation:"U"},
-                    {name:"笕尚退货",operation:"D"}
-                ],
-                operation:[],
-                express:[],
-                logistic:[],
-                directLogistic:{},
+                storage:{
+                    "C":[{name:"笕尚退货",counting_type:"包仓",using_type:"恒温"},{name:"笕尚退货",counting_type:"包仓",using_type:"恒温"}],
+                    "U":[{name:"笕尚退货",counting_type:"包仓",using_type:"恒温",
+                        minimum_area:"200",price:["0.2"],discount_type:"无减免",target_id:"10",
+                        discount_value:"20",unit_id:"m²",time_unit_id:"日",tax_rate_id:"3",amount_interval:["2"]}],
+                    "D":[{name:"笕尚退货",counting_type:"包仓",using_type:"恒温",
+                        minimum_area:"200",price:["0.2","0.1"],discount_type:"无减免",
+                        discount_value:"20",unit_id:"m²",time_unit_id:"日",tax_rate_id:"3",amount_interval:["2","5"]}],
+                    "H":{10:{name:"笕尚退货",counting_type:"包仓",using_type:"恒温",
+                            minimum_area:"200",price:["0.1","0.2"],discount_type:"无减免",
+                            discount_value:"20",unit_id:"m²",time_unit_id:"日",tax_rate_id:"3",amount_interval:["2","5"]}},
+                },
+                operation:{
+                    "C":[{name:"笕尚入库",operation_type:"入库",strategy:"特征"},{name:"笕尚入库",operation_type:"入库",strategy:"特征"}],
+                },
+                express:{
+                    "C":[{name:"笕尚快递"}],
+                },
+                logistic:{
+                    "C":[{name:"笕尚物流"}],
+                },
+                directLogistic:{
+                    "C":[{name:"笕尚直发",base_km:"10"}],
+                },
+                system:{
+                    "C":[{usage_fee:"500"}],
+                },
                 mapping:{
-                    "storage.name":"名称",
+                    "storage":{
+                        "name":"名称",
+                        "counting_type":"计费类型",
+                        "using_type":"用仓类型",
+                        "minimum_area":"最低起租面积",
+                        "discount_type":"减免类型",
+                        "discount_value":"减免值",
+                        "unit_id":"单位",
+                        "time_unit_id":"计时单位",
+                        "amount_interval":"数量-单价",
+                        "tax_rate_id":"税率",
+                    }
                 },
             },
+            selectedAudit:"storage"
+        },
+        mounted(){
+            let temp = {};
+            this.auditList.storage.U.forEach(data=>{
+                let tar = this.auditList.storage.H[data.target_id];
+                for (let key in this.auditList.mapping.storage){
+                    if (data[key]!==tar[key]){
+                        if (!temp[key]) temp[key] = this.auditList.mapping.storage[key];
+                        data[key] = this.transformData(data[key],key)+this.transformData(tar[key],key);
+                    }else data[key] = this.transformData(data[key],key);
+                }
+                if (data["price"]!==tar["price"]){
+
+                }
+            });
+            this.auditList.mapping.storage = temp;
+        },
+        methods:{
+            transformData(val,key){
+                if (!val)return;
+                switch (key) {
+                    case 'tax_rate_id':
+                        val += "%";
+                        break;
+                    case "amount_interval":
+                        let html = '<div class="float-left">';
+                        val.forEach((am,i)=>{
+                            html += "<small>"+am+"-"+val[i+1]+"("+data["price"][i]+"元)</small>";
+                        });
+                        html += "<small>"+val[val.length-1]+" +("+data["price"][val.length-1]+"元)</small></div>";
+                        val = html;
+                }
+                return val;
+            },
         },
     });
 </script>

+ 2 - 0
routes/web.php

@@ -160,6 +160,7 @@ Route::group(['prefix'=>'maintenance'],function(){
         Route::post('apiStoreExpress','PriceModelController@apiStoreExpress');
         Route::post('apiStoreLogistic','PriceModelController@apiStoreLogistic');
         Route::post('apiStoreDirectLogistic','PriceModelController@apiStoreDirectLogistic');
+        Route::post('apiStoreSystem','PriceModelController@apiStoreSystem');
         //api 获取计费模型
         Route::post('apiGetStorage','PriceModelController@apiGetStorage');
         Route::post('apiGetOperation','PriceModelController@apiGetOperation');
@@ -176,6 +177,7 @@ Route::group(['prefix'=>'maintenance'],function(){
         Route::post('apiDelLogisticItem','PriceModelController@apiDelLogisticItem');
         Route::post('apiDelDirectLogistic','PriceModelController@apiDelDirectLogistic');
         Route::post('apiDelDirectLogisticItem','PriceModelController@apiDelDirectLogisticItem');
+        Route::post('apiDelSystem','PriceModelController@apiDelSystem');
         //审核或恢复计费模型
         Route::post('auditOrRecoverModel','PriceModelController@auditOrRecoverModel');
     });

+ 5 - 0
tests/Feature/LogisticZopSyncTest.php

@@ -37,6 +37,11 @@ class LogisticZopSyncTest extends TestCase
         parent::tearDown(); // TODO: Change the autogenerated stub
     }
 
+    public function test_get()
+    {
+        LogisticZopSync::dispatch('73228206493308');
+    }
+
 
     /**
      * @test

+ 1 - 1
tests/Services/LogisticQiaoSFService/LogisticQiaoSFServiceTest.php

@@ -25,7 +25,7 @@ class LogisticQiaoSFServiceTest extends TestCase
 //        factory(\App\OrderPackage::class)->create(['logistic_number' => 'SF1335376515904',]);
 //        factory(\App\OrderPackage::class)->create(['logistic_number' => 'SF2050377278135',]);
 //        factory(\App\OrderPackage::class)->create(['logistic_number' => 'SF2060390000049',]);
-        $response = $this->logisticQiaoSFService->get(['SF1306128321691']);
+        $response = $this->logisticQiaoSFService->get(['SF2010424528947']);
         dd($response);
         $this->assertCount(3, $response);
     }