|
@@ -1538,4 +1538,266 @@ class StatisticsService extends Service
|
|
|
|
|
|
|
|
return $finalData;
|
|
return $finalData;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ public function getChannelReportItem1($data)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (empty($data['order_time'])) return [false, '年月不能为空'];
|
|
|
|
|
+ $yearMonth = $data['order_time'];
|
|
|
|
|
+
|
|
|
|
|
+ [$year, $month] = explode('-', $yearMonth);
|
|
|
|
|
+ $year = (int)$year;
|
|
|
|
|
+ $month = (int)$month;
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 计算时间范围:7月财年规则
|
|
|
|
|
+ $currentMonthTs = mktime(0, 0, 0, $month, 1, $year);
|
|
|
|
|
+ $startYear = ($month >= 7) ? $year : $year - 1;
|
|
|
|
|
+ $startTs = mktime(0, 0, 0, 7, 1, $startYear);
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 一次性获取数据
|
|
|
|
|
+ $records = DB::table('item_report')
|
|
|
|
|
+ ->whereBetween('time', [$startTs, $currentMonthTs])
|
|
|
|
|
+ ->get();
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 字段映射 (注意 24 行,若数据库无字段则设为 null 会自动补 0)
|
|
|
|
|
+ $rowFieldMapping = [
|
|
|
|
|
+ 5 => 'receipt_amount', 6 => 'pk_amount', 7 => 'cost', 8 => 'profit',
|
|
|
|
|
+ 9 => 'settle_amount', 10 => 'gl_amount', 11 => 'wl_amount',
|
|
|
|
|
+ 12 => 'ht_amount', 13 => 'zk_amount', 14 => 'cx_amount',
|
|
|
|
|
+ 15 => 'tg_amount', 16 => 'cl_amount', 17 => 'kq_amount',
|
|
|
|
|
+ 18 => 'zp_amount', 19 => 'gg_amount', 20 => 'kd_amount',
|
|
|
|
|
+ 21 => 'xsqt_amount', 22 => 'ry_amount', 23 => 'sb_amount',
|
|
|
|
|
+ 24 => null, // 退货亏损 (不良仓),暂无字段映射,填充0
|
|
|
|
|
+ 25 => 'cg_amount', 26 => 'sj_amount',
|
|
|
|
|
+ 27 => 'sx_amount', 28 => 'other_ck_amount'
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 初始化列容器 (C 到 Z)
|
|
|
|
|
+ $columns = [];
|
|
|
|
|
+ $columnKeys = range('C', 'AB');
|
|
|
|
|
+ foreach ($columnKeys as $col) {
|
|
|
|
|
+ $columns[$col] = array_fill(5, 33, 0); // 覆盖 5-33 行
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 数据分拣累加
|
|
|
|
|
+ foreach ($records as $record) {
|
|
|
|
|
+ $channel_details = $record->channel_details;
|
|
|
|
|
+ $isCurrent = ((int)$record->time === $currentMonthTs);
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($rowFieldMapping as $rowIdx => $field) {
|
|
|
|
|
+ $val = $field ? (float)($record->$field ?? 0) : 0;
|
|
|
|
|
+
|
|
|
|
|
+ if ($channel_details === '大卖场') {
|
|
|
|
|
+ if ($isCurrent) $columns['C'][$rowIdx] += $val;
|
|
|
|
|
+ $columns['F'][$rowIdx] += $val;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (($empId === 2 || $empId === 5) && $finance === '通路') {
|
|
|
|
|
+ if ($isCurrent) $columns['D'][$rowIdx] += $val;
|
|
|
|
|
+ $columns['F'][$rowIdx] += $val;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 金小勇
|
|
|
|
|
+ if ($empId === 3 && $finance === '通路') {
|
|
|
|
|
+ if ($isCurrent) $columns['G'][$rowIdx] += $val;
|
|
|
|
|
+ $columns['J'][$rowIdx] += $val;
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($empId === 3 && $finance === '联华加盟') {
|
|
|
|
|
+ if ($isCurrent) $columns['H'][$rowIdx] += $val;
|
|
|
|
|
+ $columns['J'][$rowIdx] += $val;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 沈强
|
|
|
|
|
+ if ($empId === 23 && $finance === '通路') {
|
|
|
|
|
+ if ($isCurrent) $columns['K'][$rowIdx] += $val;
|
|
|
|
|
+ $columns['N'][$rowIdx] += $val;
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($empId === 23 && $finance === '智鲸') {
|
|
|
|
|
+ if ($isCurrent) $columns['L'][$rowIdx] += $val;
|
|
|
|
|
+ $columns['N'][$rowIdx] += $val;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 王利英等组合 (O/P列)
|
|
|
|
|
+ if (in_array($empId, [7, 8, 54]) && in_array($finance, ['通路', '大卖场'])) {
|
|
|
|
|
+ if ($isCurrent) $columns['O'][$rowIdx] += $val;
|
|
|
|
|
+ $columns['P'][$rowIdx] += $val;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 叶南汝
|
|
|
|
|
+ if ($empId === 48 && $finance === '通路') {
|
|
|
|
|
+ if ($isCurrent) $columns['Q'][$rowIdx] += $val;
|
|
|
|
|
+ $columns['T'][$rowIdx] += $val;
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($empId === 48 && $finance === '大卖场') {
|
|
|
|
|
+ if ($isCurrent) $columns['R'][$rowIdx] += $val;
|
|
|
|
|
+ $columns['T'][$rowIdx] += $val;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 行政
|
|
|
|
|
+ if ($finance === '行政') {
|
|
|
|
|
+ if ($isCurrent) $columns['U'][$rowIdx] += $val;
|
|
|
|
|
+ $columns['V'][$rowIdx] += $val;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 鲍总
|
|
|
|
|
+ if ($finance === '鲍总') {
|
|
|
|
|
+ if ($isCurrent) $columns['W'][$rowIdx] += $val;
|
|
|
|
|
+ $columns['X'][$rowIdx] += $val;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 计算合计列与纵向小计
|
|
|
|
|
+ for ($i = 5; $i <= 27; $i++) {
|
|
|
|
|
+ // 合计列
|
|
|
|
|
+ $columns['E'][$i] = $columns['C'][$i] + $columns['D'][$i];
|
|
|
|
|
+ $columns['I'][$i] = $columns['G'][$i] + $columns['H'][$i];
|
|
|
|
|
+ $columns['M'][$i] = $columns['K'][$i] + $columns['L'][$i];
|
|
|
|
|
+ $columns['S'][$i] = $columns['Q'][$i] + $columns['R'][$i];
|
|
|
|
|
+
|
|
|
|
|
+ // Y/Z 总计
|
|
|
|
|
+ $columns['Y'][$i] = $columns['C'][$i] + $columns['D'][$i] + $columns['G'][$i] + $columns['H'][$i] +
|
|
|
|
|
+ $columns['K'][$i] + $columns['L'][$i] + $columns['O'][$i] + $columns['Q'][$i] +
|
|
|
|
|
+ $columns['R'][$i] + $columns['U'][$i] + $columns['W'][$i];
|
|
|
|
|
+
|
|
|
|
|
+ $columns['Z'][$i] = $columns['F'][$i] + $columns['J'][$i] + $columns['N'][$i] + $columns['P'][$i] +
|
|
|
|
|
+ $columns['T'][$i] + $columns['V'][$i] + $columns['X'][$i];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 纵向小计 (第 32 行 = 8 到 31 行累加)
|
|
|
|
|
+ foreach ($columnKeys as $col) {
|
|
|
|
|
+ $subTotal = 0;
|
|
|
|
|
+ for ($r = 8; $r <= 31; $r++) {
|
|
|
|
|
+ $subTotal += (float)($columns[$col][$r] ?? 0);
|
|
|
|
|
+ }
|
|
|
|
|
+ $columns[$col][32] = $subTotal;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 最终格式化
|
|
|
|
|
+ $finalData = [];
|
|
|
|
|
+ for ($row = 5; $row <= 32; $row++) {
|
|
|
|
|
+ $rowData = [];
|
|
|
|
|
+ foreach ($columnKeys as $colLetter) {
|
|
|
|
|
+ $val = $columns[$colLetter][$row] ?? 0;
|
|
|
|
|
+
|
|
|
|
|
+ if ($row >= 28 && $row <= 31) {
|
|
|
|
|
+ $rowData[] = ''; // 预留行填空
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $rowData[] = ($val == 0) ? '0.00' : number_format($val, 2, '.', '');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ $finalData[] = $rowData;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $finalData;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function getChannelReportItem($data)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (empty($data['order_time'])) return [false, '年月不能为空'];
|
|
|
|
|
+ $yearMonth = $data['order_time'];
|
|
|
|
|
+
|
|
|
|
|
+ [$year, $month] = explode('-', $yearMonth);
|
|
|
|
|
+ $year = (int)$year;
|
|
|
|
|
+ $month = (int)$month;
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 财年计算 (7月起算)
|
|
|
|
|
+ $currentMonthTs = mktime(0, 0, 0, $month, 1, $year);
|
|
|
|
|
+ $startYear = ($month >= 7) ? $year : $year - 1;
|
|
|
|
|
+ $startTs = mktime(0, 0, 0, 7, 1, $startYear);
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 获取数据
|
|
|
|
|
+ $records = DB::table('item_report')
|
|
|
|
|
+ ->whereBetween('time', [$startTs, $currentMonthTs])
|
|
|
|
|
+ ->get();
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 字段映射 (严格对应 B 列 5-28 行项目)
|
|
|
|
|
+ $rowFieldMapping = [
|
|
|
|
|
+ 5 => 'receipt_amount', 6 => 'pk_amount', 7 => 'cost', 8 => 'profit',
|
|
|
|
|
+ 9 => 'settle_amount', 10 => 'gl_amount', 11 => 'wl_amount', 12 => 'ht_amount',
|
|
|
|
|
+ 13 => 'zk_amount', 14 => 'cx_amount', 15 => 'tg_amount', 16 => 'cl_amount',
|
|
|
|
|
+ 17 => 'kq_amount', 18 => 'zp_amount', 19 => 'gg_amount', 20 => 'kd_amount',
|
|
|
|
|
+ 21 => 'xsqt_amount', 22 => 'ry_amount', 23 => 'sb_amount',
|
|
|
|
|
+ 24 => null, // 退货亏损 (不良仓) 预留映射位
|
|
|
|
|
+ 25 => 'cg_amount', 26 => 'sj_amount', 27 => 'sx_amount', 28 => 'other_ck_amount'
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 初始化列容器 (C 到 AB, 即第 3 列到第 28 列)
|
|
|
|
|
+ $columnKeys = [];
|
|
|
|
|
+ for ($i = 3; $i <= 28; $i++) {
|
|
|
|
|
+ $columnKeys[] = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $columns = [];
|
|
|
|
|
+ foreach ($columnKeys as $col) {
|
|
|
|
|
+ $columns[$col] = array_fill(5, 29, 0); // 初始化 5-33 行
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 渠道名称与其起始列(当月列)的映射
|
|
|
|
|
+ $channelMap = [
|
|
|
|
|
+ '大卖场' => 'C',
|
|
|
|
|
+ '杭州大红鹰超市有限公司' => 'E',
|
|
|
|
|
+ '杭州宏祐贸易有限公司' => 'G',
|
|
|
|
|
+ '联华加盟' => 'I',
|
|
|
|
|
+ '社区' => 'K',
|
|
|
|
|
+ '通路' => 'M',
|
|
|
|
|
+ '浙江汇德隆食品有限公司' => 'O',
|
|
|
|
|
+ '浙江灵峰教育后勤管理有限公司' => 'Q',
|
|
|
|
|
+ '浙江物联电子商务有限公司' => 'S',
|
|
|
|
|
+ '浙江新宇贸易有限公司' => 'U',
|
|
|
|
|
+ '智鲸' => 'W',
|
|
|
|
|
+ '行政' => 'Y',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 分拣累加
|
|
|
|
|
+ foreach ($records as $record) {
|
|
|
|
|
+ $channel = $record->channel_details;
|
|
|
|
|
+ $isCurrent = ((int)$record->time === $currentMonthTs);
|
|
|
|
|
+
|
|
|
|
|
+ if (isset($channelMap[$channel])) {
|
|
|
|
|
+ $curCol = $channelMap[$channel]; // 当月列
|
|
|
|
|
+ // 安全获取下一列(累计列)字母,避免 chr() 处理双字母失败
|
|
|
|
|
+ $accCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex(
|
|
|
|
|
+ \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($curCol) + 1
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($rowFieldMapping as $rowIdx => $field) {
|
|
|
|
|
+ $val = $field ? (float)($record->$field ?? 0) : 0;
|
|
|
|
|
+ if ($isCurrent) $columns[$curCol][$rowIdx] += $val;
|
|
|
|
|
+ $columns[$accCol][$rowIdx] += $val;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 计算横向合计 (AA, AB) 与 纵向小计 (第 33 行)
|
|
|
|
|
+ $channelStartCols = array_values($channelMap);
|
|
|
|
|
+ for ($row = 5; $row <= 28; $row++) {
|
|
|
|
|
+ foreach ($channelStartCols as $sCol) {
|
|
|
|
|
+ $aCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex(
|
|
|
|
|
+ \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($sCol) + 1
|
|
|
|
|
+ );
|
|
|
|
|
+ $columns['AA'][$row] += $columns[$sCol][$row];
|
|
|
|
|
+ $columns['AB'][$row] += $columns[$aCol][$row];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 计算纵向小计 (第 33 行 = 9 到 28 行的累加,跳过预留行)
|
|
|
|
|
+ foreach ($columnKeys as $col) {
|
|
|
|
|
+ $subTotal = 0;
|
|
|
|
|
+ for ($r = 9; $r <= 28; $r++) {
|
|
|
|
|
+ $subTotal += (float)($columns[$col][$r] ?? 0);
|
|
|
|
|
+ }
|
|
|
|
|
+ $columns[$col][33] = $subTotal;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 最终格式化输出
|
|
|
|
|
+
|
|
|
|
|
+ $finalData = [];
|
|
|
|
|
+ for ($row = 5; $row <= 33; $row++) {
|
|
|
|
|
+ // 关键:29-32行我们直接不生成数据,或者生成空
|
|
|
|
|
+ if ($row >= 29 && $row <= 32) continue;
|
|
|
|
|
+
|
|
|
|
|
+ $rowData = [];
|
|
|
|
|
+ foreach ($columnKeys as $colLetter) {
|
|
|
|
|
+ $val = $columns[$colLetter][$row] ?? 0;
|
|
|
|
|
+ $rowData[] = ($val == 0) ? '0.00' : number_format($val, 2, '.', '');
|
|
|
|
|
+ }
|
|
|
|
|
+ // 使用行号作为 Key
|
|
|
|
|
+ $finalData[$row] = $rowData;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $finalData;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|