OwnerStoreFeeReportService.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <?php
  2. namespace App\Services;
  3. use App\OwnerBillReport;
  4. use App\OwnerBillReportArchive;
  5. use App\Traits\ServiceAppAop;
  6. use App\OwnerStoreFeeReport;
  7. use Carbon\Carbon;
  8. use Illuminate\Database\Eloquent\Builder;
  9. use Illuminate\Support\Facades\DB;
  10. class OwnerStoreFeeReportService implements \App\Interfaces\SettlementBillReportInterface
  11. {
  12. const TYPE = '入库费-合计';
  13. use ServiceAppAop;
  14. use \App\Traits\SettlementBillServiceTrait;
  15. protected $modelClass = OwnerStoreFeeReport::class;
  16. /** @var $archiveService OwnerBillReportArchiveService */
  17. private $archiveService;
  18. /** @var $detailService OwnerStoreFeeDetailService */
  19. private $detailService;
  20. /**
  21. * 生成报表数据
  22. * 如果参数$counting_month为空 统计上一个月的
  23. * 如果参数$counting_month为2021-01-01 则统计2021-01-01 -- 2021-01-31之间的数据
  24. * @param null $counting_month 统计月份,默认统计上个月的 2021-05-01
  25. */
  26. public function recordReport($counting_month = null,array $ownerIds = [])
  27. {
  28. $this->detailService = app('OwnerStoreFeeDetailService');
  29. if (is_null($counting_month)) {
  30. //默认统计上个月的数据
  31. $counting_month = now()->subMonth()->startOfMonth()->toDateString();
  32. }
  33. list($start, $end) = $this->getStartAndEnd($counting_month);
  34. $builder = DB::table('owner_fee_operations')
  35. ->leftJoin('owner_fee_operation_details', 'owner_fee_operations.id', '=', 'owner_fee_operation_details.owner_fee_operation_id')
  36. ->leftJoin('owner_price_operations', 'owner_fee_operations.model_id', '=', 'owner_price_operations.id')
  37. ->selectRaw("
  38. DATE_FORMAT(owner_fee_operations.worked_at,'%Y-%m') as counting_month,
  39. owner_fee_operation_details.unit_id,
  40. owner_fee_operation_details.price,
  41. owner_price_operations.name,
  42. sum(owner_fee_operation_details.amount) as amounts ,
  43. owner_fee_operations.owner_id,
  44. owner_fee_operations.model_id,
  45. sum(owner_fee_operation_details.price*owner_fee_operation_details.amount) as fee,
  46. sum(owner_fee_operation_details.price*owner_fee_operation_details.amount*owner_fee_operations.tax_rate) as tax_fee
  47. ")
  48. ->whereBetween('owner_fee_operations.worked_at', [$start, $end])
  49. ->whereNotNull('owner_fee_operation_details.price')
  50. ->whereNotNull('owner_fee_operation_details.amount')
  51. ->whereIn('model_id', \App\OwnerPriceOperation::query()->select('id')->where('operation_type', '入库'));
  52. if (!empty($ownerIds)) {
  53. $builder->whereIn('owner_fee_operations.owner_id', $ownerIds);
  54. }
  55. $details = $builder->groupBy(
  56. 'counting_month',
  57. 'owner_id',
  58. 'unit_id',
  59. 'price',
  60. 'model_id'
  61. )
  62. ->get();
  63. $reports = [];
  64. foreach ($details as $detail) {
  65. $counting_month = Carbon::parse($detail->counting_month)->startOfMonth()->toDateString();
  66. $ownerBillReport = OwnerBillReport::query()
  67. ->selectRaw("id")
  68. ->where('owner_id', $detail->owner_id)
  69. ->where('counting_month', $counting_month)->first();
  70. $reports[] = [
  71. 'owner_bill_report_id' => $ownerBillReport->id ?? null,
  72. 'owner_id' => $detail->owner_id,
  73. 'counting_month' => $counting_month,
  74. 'unit_id' => $detail->unit_id,
  75. 'unit_price' => $detail->price,
  76. 'amount' => $detail->amounts,
  77. 'fee' => $detail->fee,
  78. 'work_name' => $detail->name,
  79. 'model_id' => $detail->model_id,
  80. 'tax_fee' => $detail->tax_fee,
  81. ];
  82. }
  83. $reports_chunked = array_chunk($reports, 1000);
  84. //保证幂等性 插入前删除该月的统计数据
  85. OwnerStoreFeeReport::query()->where('counting_month', $counting_month)->delete();
  86. foreach ($reports_chunked as $items) {
  87. OwnerStoreFeeReport::query()->insertOrIgnore($items);
  88. }
  89. }
  90. public function get(array $kvPairs): array
  91. {
  92. $this->archiveService = app('OwnerBillReportArchiveService');
  93. $this->detailService = app('OwnerStoreFeeDetailService');
  94. if ($this->archiveService->isArchived($kvPairs['counting_month'], $kvPairs['owner_id'], $kvPairs['type']) == 1) {
  95. //查询存档数据
  96. $archived = $this->archiveService->get($kvPairs);
  97. $reports = collect($archived->information['reports']);
  98. $totalAmount = $archived->information['totalAmount'];
  99. $totalFee = $archived->information['totalFee'];
  100. $owner_price_operation_fees = collect($archived->information['owner_price_operation_fees']);
  101. } else {
  102. $reports = $this->getSql($kvPairs['owner_id'], $kvPairs['counting_month'])->get();
  103. $totalAmount = $reports->sum('amount');
  104. $totalFee = number_format($reports->sum('fee'), 2);
  105. $owner_price_operation_fees = OwnerStoreFeeReport::query()
  106. ->selectRaw("sum(fee) as fee,work_name")
  107. ->where('owner_id', $kvPairs['owner_id'])
  108. ->where('counting_month', $kvPairs['counting_month'])
  109. ->groupBy('work_name')->get();
  110. }
  111. return array($reports, $totalAmount, $totalFee, $owner_price_operation_fees);
  112. }
  113. /**
  114. * @param $owner_id
  115. * @param $counting_month
  116. * @return Builder
  117. */
  118. public function getSql($owner_id, $counting_month): Builder
  119. {
  120. return OwnerStoreFeeReport::query()
  121. ->with(['unit:id,name'])
  122. ->where('owner_id', $owner_id)
  123. ->where('counting_month', $counting_month);
  124. }
  125. public function switchType($type)
  126. {
  127. // TODO: Implement switchType() method.
  128. }
  129. public function buildExport($details): array
  130. {
  131. // TODO: Implement buildExport() method.
  132. }
  133. public function confirmBill($counting_month, $owner_id)
  134. {
  135. $billReport = OwnerBillReport::query()
  136. ->select('storage_fee', 'id')
  137. ->where('owner_id', $owner_id)
  138. ->where('counting_month', $counting_month)
  139. ->firstOr(function () {
  140. return new OwnerBillReport();
  141. });
  142. list($reports, $totalAmount, $totalFee, $owner_price_operation_fees) = $this->get([
  143. 'owner_id' => $owner_id,
  144. 'counting_month' => $counting_month,
  145. 'type' => $this::TYPE,
  146. ]);
  147. OwnerBillReportArchive::query()->create([
  148. 'owner_bill_report_id' => $billReport->id ?? null,
  149. 'owner_id' => $owner_id,
  150. 'counting_month' => $counting_month,
  151. 'type' => $this::TYPE,
  152. 'archiver_id' => auth()->id(),
  153. 'archived_at' => now(),
  154. 'information' => [
  155. 'reports' => $reports,
  156. 'totalAmount' => $totalAmount,
  157. 'totalFee' => $totalFee,
  158. 'owner_price_operation_fees' => $owner_price_operation_fees
  159. ],
  160. ]);
  161. $this->confirmBillFeeTotal($counting_month, $owner_id);
  162. }
  163. }