OwnerStoreFeeReportService.php 8.7 KB

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