| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509 |
- <?php
- namespace App\Services;
- use App\OrderIssue;
- use App\Owner;
- use App\OwnerBillReport;
- use App\OwnerPriceOperation;
- use App\OwnerPriceOperationItem;
- use App\OwnerStoreOutFeeReport;
- use App\Traits\ServiceAppAop;
- use App\OwnerFeeTotal;
- use App\Traits\SettlementBillServiceTrait;
- use Illuminate\Database\Eloquent\Builder;
- class OwnerFeeTotalService
- {
- const TYPE = '总费用';
- use ServiceAppAop;
- use SettlementBillServiceTrait;
- protected $modelClass = OwnerFeeTotal::class;
- /**
- * 生成统计数据
- * @param string|null $counting_month string 统计月份默认为上一个月
- * @param array $ownerIds
- */
- public function record(string $counting_month = null, array $ownerIds = [])
- {
- if (is_null($counting_month)) {
- $counting_month = now()->subMonth()->startOfMonth()->toDateString();
- }
- /**
- * 仓储。入库,出库
- * 1. 查到所有货主
- * 2. 遍历货主
- * 3. 获得货主下的计费模型,将计费模型里面的数据转换成“描述”
- * 4. 查询相关表,获得指定计费模型下的费用总和(含税费)
- *
- * 配送,加工,系统使用,杂项
- * 1. 查询对应表的总和即可,不需关联计费模型
- *
- * 理赔
- * 1. 暂不明确
- *
- * 优惠
- * 1. 一个字段,在结算管理-账单却认下添加一个优惠输入的字段
- *
- * 税率
- * 1. 计算得出:总税费/总金额
- */
- //仓储:ownerStoragePriceModels。入库,出库:ownerPriceOperations
- $builder = Owner::query()
- ->with([
- "ownerStoragePriceModels.unit:id,name",
- "ownerStoragePriceModels.timeUnit:id,name",
- "ownerPriceOperations" => function ($query) {
- /** @var Builder $query */
- $query->with(["items" => function ($query) {
- /** @var Builder $query */
- $query->with(['unit'])->orderByRaw("CASE strategy WHEN '起步' THEN 1 WHEN '默认' THEN 2 WHEN '特征' THEN 3 END");
- }]);
- }])
- ->where('deleted_at', '>=', now()->subMonth()->startOfMonth())
- ->orWhereNull('deleted_at');
- if (!empty($ownerIds)) {
- $builder->whereIn('id', $ownerIds);
- }
- $owners = $builder->get();
- foreach ($owners as $owner) {
- $information = $this->buildInformation($owner, $counting_month);
- $ownerFeeTotal = [];
- $ownerFeeTotal['information'] = $information;
- //快递费
- $ownerFeeTotal = $this->buildExpressFee($owner, $counting_month, $ownerFeeTotal);
- //物流费
- $ownerFeeTotal = $this->buildLogisticFee($owner, $counting_month, $ownerFeeTotal);
- //加工
- $ownerFeeTotal = $this->buildProcessFee($owner, $counting_month, $ownerFeeTotal);
- //系统使用费
- $ownerFeeTotal = $this->buildSystemFee($counting_month, $owner, $ownerFeeTotal);
- //杂项费
- $ownerFeeTotal = $this->buildSundryFee($owner, $counting_month, $ownerFeeTotal);
- //理赔
- $ownerFeeTotal = $this->buildIndemnityFee($counting_month, $owner, $ownerFeeTotal);
- // 包材费
- $ownerFeeTotal = $this->buildPackingMaterialFee($owner, $counting_month, $ownerFeeTotal);
- // 卸货费
- $ownerFeeTotal = $this->buildUnloadFee($owner, $counting_month, $ownerFeeTotal);
- //总费用 和 总税费
- list($totalFee, $totalTaxFee, $ownerFeeTotal) = $this->calTotalFeeAndTotalTaxFee($ownerFeeTotal);
- //税率
- $ownerFeeTotal = $this->calTaxRate($totalTaxFee, $totalFee, $ownerFeeTotal);
- $insertData = $this->buildInsertData($owner, $counting_month, $ownerFeeTotal);
- $this->createOrUpdate($owner, $counting_month, $insertData);
- }
- }
- public function get(array $kvPairs)
- {
- return OwnerFeeTotal::query()
- ->where('owner_id', $kvPairs['owner_id'])
- ->where('counting_month', $kvPairs['counting_month'])
- ->firstOr(function (){
- return new OwnerFeeTotal();
- });
- }
- /**
- * 出库入库描述
- * @param $ownerPriceOperation
- * @return array
- */
- private function buildPriceRemarks($ownerPriceOperation): array
- {
- //起步: 3 件 / 2.7000元 (满减单价: 0-19999 单(2.7元) , 20000-49999 单(2.5元) , 50000-99999 单(2元) , 100000+ 单(1.6元) )
- //默认续费: 1 件 / 0.5000元 (满减单价: 0-19999 单(0.5元) , 20000-49999 单(0.4元) , 50000-99999 单(0.3元) , 100000+ 单(0.2元) )
- $discount_counts = explode(',', $ownerPriceOperation->discount_count);
- $priceRemarks = [];
- foreach ($ownerPriceOperation->items as $operationItem) {
- $discount_prices = explode(',', $operationItem->discount_price);
- $strategy = $operationItem->strategy == '起步' ? '起步' : '默认续费';
- $unit_name = $operationItem->unit->name ?? '个';
- $priceRemark = "{$strategy}: {$operationItem->amount} {$unit_name}/{$operationItem->unit_price}元";
- if (!empty($discount_prices)) {
- $priceRemark .= "(满减单价:";
- for ($i = 0; $i < count($discount_counts) - 1; $i++) {
- $next_discount_count = $discount_counts[$i + 1] ?? '+';
- $discount_count = $discount_counts[$i] ?? '';
- $discount_price = $discount_prices[$i] ?? '';
- $priceRemark .= "{$discount_count}-{$next_discount_count} {$unit_name} {$discount_price}元,";
- }
- $priceRemark .= ")";
- }
- $priceRemarks[] = $priceRemark;
- }
- return $priceRemarks;
- }
- /**
- * @param $owner
- * @param $counting_month
- * @return array|array[]
- */
- private function buildInformation($owner, $counting_month): array
- {
- //获取特征信息
- $features = app("FeatureService")->getMapArray();
- OwnerPriceOperation::$features = $features;
- OwnerPriceOperationItem::$features = $features;
- foreach ($owner->ownerPriceOperations as &$operation) {
- $operation["featureFormat"] = $operation->featureFormat;
- $operation["isRejected"] = $operation->type_mark === 0;
- foreach ($operation->items as &$item) {
- $item["featureFormat"] = $item->featureFormat;
- if ($item["strategy"] == "起步") $item["type"] = $item["amount"] ? 0 : 1;
- }
- }
- $information = [
- //仓储
- 'storageFee' => [],
- //入库
- 'storeFee' => [],
- //出库
- 'storeOutFee' => [],
- ];
- //仓储
- foreach ($owner->ownerStoragePriceModels as $ownerStoragePriceModel) {
- /**@var $areaFeeService SettlementBillsAreaFeeService */
- $areaFeeService = app('SettlementBillsAreaFeeService');
- $remark = "起租面积:{$ownerStoragePriceModel->minimum_area},{$ownerStoragePriceModel->price[0]}元/{$ownerStoragePriceModel->unit->name}/{$ownerStoragePriceModel->timeUnit->name}";
- $information['storageFee'][] = [
- 'name' => $ownerStoragePriceModel->name,
- 'remark' => $remark,
- 'id' => $ownerStoragePriceModel->id,
- 'fee' => $areaFeeService->getTotalFee($owner->id, $counting_month)->storage_fee ?? 0,
- 'tax_fee' => $areaFeeService->getTotalFee($owner->id, $counting_month)->storage_tax_fee ?? 0
- ];
- }
- $ownerPriceOperationsGrouped = $owner->ownerPriceOperations->groupBy('operation_type');
- //入库
- $ownerStoreFeeReports = \App\OwnerStoreFeeReport::query()
- ->selectRaw("
- sum(fee) as fee,
- sum(tax_fee) as tax_fee,
- model_id
- ")
- ->where('counting_month', $counting_month)
- ->where('owner_id', $owner->id)
- ->groupBy('model_id')
- ->get();
- $ownerStoreFeeReportsGroupByModelId = $ownerStoreFeeReports->groupBy('model_id')->toArray();
- foreach ($ownerPriceOperationsGrouped['入库'] ?? [] as $ownerPriceOperationsGroupedItem) {
- try {
- $fee = $ownerStoreFeeReportsGroupByModelId[$ownerPriceOperationsGroupedItem->id][0]['fee'];
- } catch (\Exception $e) {
- $fee = $ownerStoreFeeReportsGroupByModelId[$ownerPriceOperationsGroupedItem->target_id][0]['fee'] ?? 0;
- $ownerPriceOperationsGroupedItem = OwnerPriceOperation::query()->with(['items'])->find($ownerPriceOperationsGroupedItem->target_id);
- }
- if ($fee > 0) {
- $information['storeFee'][] = [
- 'name' => $ownerPriceOperationsGroupedItem->name,
- 'remark' => $this->buildPriceRemarks($ownerPriceOperationsGroupedItem),
- 'id' => $ownerPriceOperationsGroupedItem->id,
- 'fee' => $fee,
- 'tax_fee' => $ownerStoreFeeReportsGroupByModelId[$ownerPriceOperationsGroupedItem->id][0]['tax_fee'] ?? 0,
- ];
- }
- }
- //出库
- $ownerStoreOutFeeReports = OwnerStoreOutFeeReport::query()
- ->selectRaw("
- sum(fee) as fee,
- sum(tax_fee) as tax_fee,
- model_id
- ")
- ->where('counting_month', $counting_month)
- ->where('owner_id', $owner->id)
- ->groupBy('model_id')
- ->get();
- $ownerStoreOutFeeReportsGroupByModelId = $ownerStoreOutFeeReports->groupBy('model_id')->toArray();
- foreach ($ownerPriceOperationsGrouped['出库'] ?? [] as $ownerPriceOperationsGroupedItem) {
- try {
- $fee = $ownerStoreOutFeeReportsGroupByModelId[$ownerPriceOperationsGroupedItem->id][0]['fee'];
- } catch (\Exception $e) {
- $fee = $ownerStoreOutFeeReportsGroupByModelId[$ownerPriceOperationsGroupedItem->target_id][0]['fee'] ?? 0;
- $ownerPriceOperationsGroupedItem = OwnerPriceOperation::query()->with(['items'])->find($ownerPriceOperationsGroupedItem->target_id);
- }
- if ($fee > 0) {
- $information['storeOutFee'][] = [
- 'name' => $ownerPriceOperationsGroupedItem->name,
- 'remark' => $this->buildPriceRemarks($ownerPriceOperationsGroupedItem),
- 'id' => $ownerPriceOperationsGroupedItem->id,
- 'fee' => $fee,
- 'tax_fee' => $ownerStoreOutFeeReportsGroupByModelId[$ownerPriceOperationsGroupedItem->id][0]['tax_fee'] ?? 0,
- ];
- }
- }
- return $information;
- }
- /**
- * @param $owner
- * @param string|null $counting_month
- * @param array $ownerFeeTotal
- * @return array
- */
- private function buildExpressFee($owner, ?string $counting_month, array $ownerFeeTotal): array
- {
- /**@var $expressFeeService OwnerLogisticFeeReportService */
- $expressFeeService = app('OwnerLogisticFeeReportService');
- $expressFeeTotal = $expressFeeService->getTotalFee($owner->id, $counting_month);
- $ownerFeeTotal ['expressFee'] = [
- 'fee' => $expressFeeTotal->fee ?? 0,
- 'tax_fee' => $expressFeeTotal->tax_fee ?? 0,
- ];
- return $ownerFeeTotal;
- }
- /**
- * @param $owner
- * @param string|null $counting_month
- * @param array $ownerFeeTotal
- * @return array
- */
- private function buildLogisticFee($owner, ?string $counting_month, array $ownerFeeTotal): array
- {
- /**@var $waybillSettlementBillService OwnerWaybillSettlementBillService */
- $waybillSettlementBillService = app('OwnerWaybillSettlementBillService');
- $logisticFeeTotal = $waybillSettlementBillService->getTotalFee($owner->id, $counting_month);
- $ownerFeeTotal ['logisticFee'] = [
- 'fee' => $logisticFeeTotal->fee ?? 0,
- 'tax_fee' => $logisticFeeTotal->tax_fee ?? 0,
- ];
- return $ownerFeeTotal;
- }
- /**
- * @param $owner
- * @param string|null $counting_month
- * @param array $ownerFeeTotal
- * @return array
- */
- private function buildProcessFee($owner, ?string $counting_month, array $ownerFeeTotal): array
- {
- /**@var $ownerProcessSettlementBillService OwnerProcessSettlementBillService */
- $ownerProcessSettlementBillService = app('OwnerProcessSettlementBillService');
- $processFeeTotal = $ownerProcessSettlementBillService->getTotalFee($owner->id, $counting_month);
- $ownerFeeTotal ['processFee'] = [
- 'fee' => $processFeeTotal->fee ?? 0,
- 'tax_fee' => $processFeeTotal->tax_fee ?? 0,
- ];
- return $ownerFeeTotal;
- }
- /**
- * @param string|null $counting_month
- * @param $owner
- * @param array $ownerFeeTotal
- * @return array
- */
- private function buildSystemFee(?string $counting_month, $owner, array $ownerFeeTotal): array
- {
- $ownerBillReport = OwnerBillReport::query()
- ->where('counting_month', $counting_month)
- ->where('owner_id', $owner->id)
- ->first();
- $ownerFeeTotal ['systemFee'] = [
- 'fee' => $ownerBillReport->other_fee ?? 0,
- 'tax_fee' => $ownerBillReport->other_tax_fee ?? 0,
- ];
- return $ownerFeeTotal;
- }
- /**
- * @param $owner
- * @param string|null $counting_month
- * @param array $ownerFeeTotal
- * @return array
- */
- private function buildSundryFee($owner, ?string $counting_month, array $ownerFeeTotal): array
- {
- /**@var $ownerSundryFeeDetailService OwnerSundryFeeDetailService */
- $ownerSundryFeeDetailService = app('OwnerSundryFeeDetailService');
- $sundryFeeTotals = $ownerSundryFeeDetailService->getTotalFee($owner->id, $counting_month);
- if (!$sundryFeeTotals->isEmpty()) {
- foreach ($sundryFeeTotals as $sundryFeeTotal) {
- $ownerFeeTotal ['sundryFee'][] = [
- 'type' => $sundryFeeTotal->type,
- 'fee' => $sundryFeeTotal->fee,
- ];
- }
- } else {
- $ownerFeeTotal ['sundryFee'] = [];
- }
- return $ownerFeeTotal;
- }
- /**
- * @param string|null $counting_month
- * @param $owner
- * @param array $ownerFeeTotal
- * @return array
- */
- private function buildIndemnityFee(?string $counting_month, $owner, array $ownerFeeTotal): array
- {
- list($start, $end) = $this->getStartAndEnd($counting_month);
- $indemnityFee = OrderIssue::query()
- ->selectRaw("sum(baoshi_indemnity_money) as fee,owner_id,order_id")
- ->leftJoin('orders', 'order_issues.order_id', '=', 'orders.id')
- ->where('owner_id', $owner->id)
- ->whereBetween('order_issues.created_at', [$start, $end])
- ->whereBetween('orders.created_at', [$start, $end])
- ->first();
- $ownerFeeTotal ['indemnityFee'] = [
- 'fee' => $indemnityFee->fee ?? 0,
- ];
- return $ownerFeeTotal;
- }
- /**
- * @param $owner
- * @param string|null $counting_month
- * @param array $ownerFeeTotal
- * @return array
- */
- private function buildPackingMaterialFee($owner, ?string $counting_month, array $ownerFeeTotal): array
- {
- /**@var $packingMaterialFeeService OwnerProcurementSettlementBillService */
- $packingMaterialFeeService = app('OwnerProcurementSettlementBillService');
- $packingMaterialFee = $packingMaterialFeeService->getTotalFee($owner->id, $counting_month);
- $ownerFeeTotal ['packingMaterialFee'] = [
- 'fee' => $packingMaterialFee ?? 0,
- ];
- return $ownerFeeTotal;
- }
- /**
- * @param $owner
- * @param string|null $counting_month
- * @param array $ownerFeeTotal
- * @return array
- */
- private function buildUnloadFee($owner, ?string $counting_month, array $ownerFeeTotal): array
- {
- /**@var $unloadService OwnerDischargeTaskSettlementBillService */
- $unloadService = app('OwnerDischargeTaskSettlementBillService');
- $unloadFee = $unloadService->getTotalFee($owner->id, $counting_month);
- $ownerFeeTotal ['unloadFee'] = [
- 'fee' => $unloadFee ?? 0,
- ];
- return $ownerFeeTotal;
- }
- /**
- * @param array $ownerFeeTotal
- * @return array
- */
- private function calTotalFeeAndTotalTaxFee(array $ownerFeeTotal): array
- {
- $totalFee = 0;
- $totalTaxFee = 0;
- foreach ($ownerFeeTotal as $key => $ownerFeeTotalItem) {
- if ($key == 'information') {
- list($totalFee, $totalTaxFee) = $this->calInformationTotalFeeAndTotalTaxFee($ownerFeeTotalItem, $totalFee, $totalTaxFee);
- } else if ($key == 'sundryFee') {
- foreach ($ownerFeeTotalItem as $sundryFeeItem) {
- $totalFee += $sundryFeeItem['fee'] ?? 0;
- }
- } else {
- $totalFee += $ownerFeeTotalItem['fee'] ?? 0;
- $totalTaxFee += $ownerFeeTotalItem['tax_fee'] ?? 0;
- }
- }
- $ownerFeeTotal['totalFee'] = $totalFee;
- $ownerFeeTotal['totalTaxFee'] = $totalTaxFee;
- return array($totalFee, $totalTaxFee, $ownerFeeTotal);
- }
- /**
- * @param $totalTaxFee
- * @param $totalFee
- * @param $ownerFeeTotal
- * @return mixed
- */
- private function calTaxRate($totalTaxFee, $totalFee, $ownerFeeTotal)
- {
- try {
- $taxRate = ($totalTaxFee / $totalFee) * 100 ?? 0;
- } catch (\Exception $e) {
- $taxRate = 0;
- }
- $ownerFeeTotal['taxRate'] = $taxRate;
- return $ownerFeeTotal;
- }
- /**
- * @param $owner
- * @param string|null $counting_month
- * @param $ownerFeeTotal
- * @return array
- */
- private function buildInsertData($owner, ?string $counting_month, $ownerFeeTotal): array
- {
- return [
- 'owner_id' => $owner->id,
- 'counting_month' => $counting_month,
- 'information' => $ownerFeeTotal['information'],
- 'fee' => $ownerFeeTotal['totalFee'],
- 'logistic_fee' => $ownerFeeTotal['logisticFee']['fee'],
- 'logistic_tax_fee' => $ownerFeeTotal['logisticFee']['tax_fee'],
- 'express_fee' => $ownerFeeTotal['expressFee']['fee'],
- 'express_tax_fee' => $ownerFeeTotal['expressFee']['tax_fee'],
- 'process_fee' => $ownerFeeTotal['processFee']['fee'],
- 'process_tax_fee' => $ownerFeeTotal['processFee']['tax_fee'],
- 'system_fee' => $ownerFeeTotal['systemFee']['fee'],
- 'system_tax_fee' => $ownerFeeTotal['systemFee']['tax_fee'],
- 'sundry_information' => $ownerFeeTotal['sundryFee'],
- 'packing_material_fee' => $ownerFeeTotal['packingMaterialFee']['fee'],
- 'unload_fee' => $ownerFeeTotal['unloadFee']['fee'],
- 'tax_rate' => $ownerFeeTotal['taxRate'],
- 'indemnity_fee' => $ownerFeeTotal['indemnityFee']['fee'],
- ];
- }
- /**
- * @param $ownerFeeTotalItem
- * @param $totalFee
- * @param $totalTaxFee
- * @return array|int[]
- */
- private function calInformationTotalFeeAndTotalTaxFee($ownerFeeTotalItem, $totalFee, $totalTaxFee): array
- {
- foreach ($ownerFeeTotalItem as $ownerFeeTotalItemOne) {
- foreach ($ownerFeeTotalItemOne as $feeItem) {
- $totalFee += $feeItem['fee'] ?? 0;
- $totalTaxFee += $feeItem['tax_fee'] ?? 0;
- }
- }
- return array($totalFee, $totalTaxFee);
- }
- /**
- * @param $owner
- * @param string|null $counting_month
- * @param array $insertData
- */
- private function createOrUpdate($owner, ?string $counting_month, array $insertData): void
- {
- if (OwnerFeeTotal::query()->where('owner_id', $owner->id)->where('counting_month', $counting_month)->exists()) {
- OwnerFeeTotal::query()
- ->where('owner_id', $owner->id)
- ->where('counting_month', $counting_month)
- ->update($insertData);
- } else {
- OwnerFeeTotal::query()
- ->where('owner_id', $owner->id)
- ->where('counting_month', $counting_month)
- ->create($insertData);
- }
- }
- }
|