|
|
@@ -92,6 +92,15 @@ class UnifiedCostCalculationService
|
|
|
Db::rollback();
|
|
|
$this->logError($e);
|
|
|
return $this->buildErrorResponse($e);
|
|
|
+ } catch (\Throwable $t) { // 添加更广泛的异常捕获
|
|
|
+ Db::rollback();
|
|
|
+ Log::error("统一成本核算失败(Throwable): " . $t->getMessage() . " at " . $t->getFile() . ":" . $t->getLine());
|
|
|
+ return [
|
|
|
+ 'success' => false,
|
|
|
+ 'message' => '成本核算失败: ' . $t->getMessage(),
|
|
|
+ 'error' => $t->getMessage(),
|
|
|
+ 'trace' => $t->getTraceAsString()
|
|
|
+ ];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -354,50 +363,69 @@ class UnifiedCostCalculationService
|
|
|
$allocationResults = [];
|
|
|
|
|
|
foreach ($workOrderHours as $workOrder) {
|
|
|
- $machineCode = $workOrder['sczl_jtbh'] ?? '';
|
|
|
- $hours = floatval($workOrder['占用机时'] ?? 0);
|
|
|
+ try {
|
|
|
+ $machineCode = $workOrder['sczl_jtbh'] ?? '';
|
|
|
+ $hours = floatval($workOrder['占用机时'] ?? 0);
|
|
|
+
|
|
|
+ if (empty($machineCode) ||
|
|
|
+ !isset($machineUtilities[$machineCode]) ||
|
|
|
+ $machineUtilities[$machineCode]['总费用'] <= 0 ||
|
|
|
+ !isset($machineTotalHours[$machineCode]) ||
|
|
|
+ $machineTotalHours[$machineCode] <= 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $allocationRatio = $hours / $machineTotalHours[$machineCode];
|
|
|
+ $allocatedAmount = round($machineUtilities[$machineCode]['总费用'] * $allocationRatio, 2);
|
|
|
|
|
|
- if (empty($machineCode) ||
|
|
|
- !isset($machineUtilities[$machineCode]) ||
|
|
|
- $machineUtilities[$machineCode]['总费用'] <= 0 ||
|
|
|
- !isset($machineTotalHours[$machineCode]) ||
|
|
|
- $machineTotalHours[$machineCode] <= 0) {
|
|
|
+ $uniqueKey = $this->getWorkOrderUniqueKey($workOrder);
|
|
|
+
|
|
|
+ $allocationResults[$uniqueKey] = [
|
|
|
+ 'unique_key' => $uniqueKey,
|
|
|
+ 'sczl_gdbh' => $workOrder['sczl_gdbh'] ?? '',
|
|
|
+ 'sczl_yjno' => $workOrder['sczl_yjno'] ?? '',
|
|
|
+ 'sczl_gxh' => $workOrder['sczl_gxh'] ?? '',
|
|
|
+ 'sczl_jtbh' => $machineCode,
|
|
|
+ '占用机时' => $hours,
|
|
|
+ '分摊比例' => $allocationRatio,
|
|
|
+ '分摊金额' => $allocatedAmount,
|
|
|
+ '机台总费用' => $machineUtilities[$machineCode]['总费用'],
|
|
|
+ '机台总工时' => $machineTotalHours[$machineCode],
|
|
|
+ ];
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error("分摊水电到工单时出错: " . $e->getMessage());
|
|
|
continue;
|
|
|
}
|
|
|
-
|
|
|
- $allocationRatio = $hours / $machineTotalHours[$machineCode];
|
|
|
- $allocatedAmount = round($machineUtilities[$machineCode]['总费用'] * $allocationRatio, 2);
|
|
|
-
|
|
|
- $uniqueKey = $this->getWorkOrderUniqueKey($workOrder);
|
|
|
-
|
|
|
- $allocationResults[$uniqueKey] = [
|
|
|
- 'unique_key' => $uniqueKey,
|
|
|
- 'sczl_gdbh' => $workOrder['sczl_gdbh'] ?? '',
|
|
|
- 'sczl_yjno' => $workOrder['sczl_yjno'] ?? '',
|
|
|
- 'sczl_gxh' => $workOrder['sczl_gxh'] ?? '',
|
|
|
- 'sczl_jtbh' => $machineCode,
|
|
|
- '占用机时' => $hours,
|
|
|
- '分摊比例' => $allocationRatio,
|
|
|
- '分摊金额' => $allocatedAmount,
|
|
|
- '机台总费用' => $machineUtilities[$machineCode]['总费用'],
|
|
|
- '机台总工时' => $machineTotalHours[$machineCode],
|
|
|
- ];
|
|
|
}
|
|
|
|
|
|
return $allocationResults;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* 获取工单唯一键
|
|
|
*/
|
|
|
- protected function getWorkOrderUniqueKey(array $workOrder): string
|
|
|
+ protected function getWorkOrderUniqueKey($workOrder): string
|
|
|
{
|
|
|
- return implode('-', [
|
|
|
- $workOrder['sczl_gdbh'] ?? '',
|
|
|
- $workOrder['sczl_yjno'] ?? '',
|
|
|
- $workOrder['sczl_gxh'] ?? '',
|
|
|
- $workOrder['sczl_jtbh'] ?? ''
|
|
|
- ]);
|
|
|
+ // 确保参数是数组且包含必要的键
|
|
|
+ if (!is_array($workOrder)) {
|
|
|
+ Log::error("getWorkOrderUniqueKey 参数不是数组: " . gettype($workOrder));
|
|
|
+ return 'invalid-' . uniqid();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保所有需要的键都存在
|
|
|
+ $gdbh = $workOrder['sczl_gdbh'] ?? $workOrder['工单编号'] ?? '';
|
|
|
+ $yjno = $workOrder['sczl_yjno'] ?? $workOrder['印件号'] ?? '';
|
|
|
+ $gxh = $workOrder['sczl_gxh'] ?? $workOrder['工序号'] ?? '';
|
|
|
+ $jtbh = $workOrder['sczl_jtbh'] ?? $workOrder['机器编号'] ?? '';
|
|
|
+
|
|
|
+ return sprintf(
|
|
|
+ '%s-%s-%s-%s',
|
|
|
+ $gdbh,
|
|
|
+ $yjno,
|
|
|
+ $gxh,
|
|
|
+ $jtbh
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -405,7 +433,8 @@ class UnifiedCostCalculationService
|
|
|
*/
|
|
|
protected function updateDirectUtilitiesToCostDetails(array $allocationResults): void
|
|
|
{
|
|
|
- if (empty($allocationResults)) {
|
|
|
+ if (empty($allocationResults) || empty($this->monthlyCostDetails)) {
|
|
|
+ Log::warning("水电费分配结果或成本明细数据为空,无法更新");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
@@ -413,13 +442,18 @@ class UnifiedCostCalculationService
|
|
|
$totalAllocatedAmount = 0;
|
|
|
|
|
|
foreach ($this->monthlyCostDetails as &$costDetail) {
|
|
|
- $uniqueKey = $this->getWorkOrderUniqueKey($costDetail);
|
|
|
-
|
|
|
- if (isset($allocationResults[$uniqueKey])) {
|
|
|
- $allocatedAmount = $allocationResults[$uniqueKey]['分摊金额'];
|
|
|
- $costDetail['直接水电'] = $allocatedAmount;
|
|
|
- $totalAllocatedAmount += $allocatedAmount;
|
|
|
- $updatedCount++;
|
|
|
+ try {
|
|
|
+ $uniqueKey = $this->getWorkOrderUniqueKey($costDetail);
|
|
|
+
|
|
|
+ if (isset($allocationResults[$uniqueKey])) {
|
|
|
+ $allocatedAmount = $allocationResults[$uniqueKey]['分摊金额'];
|
|
|
+ $costDetail['直接水电'] = $allocatedAmount;
|
|
|
+ $totalAllocatedAmount += $allocatedAmount;
|
|
|
+ $updatedCount++;
|
|
|
+ }
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error("更新直接水电费时出错: " . $e->getMessage());
|
|
|
+ continue;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -641,17 +675,26 @@ class UnifiedCostCalculationService
|
|
|
*/
|
|
|
protected function calculateApportionedUtilities(array $param): void
|
|
|
{
|
|
|
- $month = $param['month'];
|
|
|
- $sysId = $param['sys_id'] ?? '';
|
|
|
+ try {
|
|
|
+ $month = $param['month'];
|
|
|
+ $sysId = $param['sys_id'] ?? '';
|
|
|
|
|
|
- $utilityData = $this->fetchApportionedUtilities($month);
|
|
|
- if (empty($utilityData)) {
|
|
|
- return;
|
|
|
- }
|
|
|
+ $utilityData = $this->fetchApportionedUtilities($month);
|
|
|
+ if (empty($utilityData)) {
|
|
|
+ Log::info("{$month}月份未找到分摊水电数据");
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- $machineAllocations = $this->calculateMachineAllocations($utilityData);
|
|
|
- $this->generateAllocationFactors($machineAllocations, $month, $sysId);
|
|
|
- $this->allocateApportionedUtilities($machineAllocations);
|
|
|
+ $machineAllocations = $this->calculateMachineAllocations($utilityData);
|
|
|
+
|
|
|
+ if (!empty($machineAllocations)) {
|
|
|
+ $this->generateAllocationFactors($machineAllocations, $month, $sysId);
|
|
|
+ $this->allocateApportionedUtilities($machineAllocations);
|
|
|
+ }
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error("计算分摊水电时出错: " . $e->getMessage());
|
|
|
+ throw new Exception("分摊水电计算失败: " . $e->getMessage());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -674,19 +717,25 @@ class UnifiedCostCalculationService
|
|
|
$machineHours = $this->getMachineHours();
|
|
|
|
|
|
foreach ($utilityData as $item) {
|
|
|
- $subject = $this->simplifySubjectName($item['科目名称']);
|
|
|
- $amount = $this->calculateUtilityAmount($item);
|
|
|
+ try {
|
|
|
+ $subject = $this->simplifySubjectName($item['科目名称']);
|
|
|
+ $amount = $this->calculateUtilityAmount($item);
|
|
|
+
|
|
|
+ if ($amount <= 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- if ($amount <= 0) {
|
|
|
+ $this->allocateBySubject($allocations, $subject, $amount, $machineHours);
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error("计算机台分摊金额时出错: " . $e->getMessage());
|
|
|
continue;
|
|
|
}
|
|
|
-
|
|
|
- $this->allocateBySubject($allocations, $subject, $amount, $machineHours);
|
|
|
}
|
|
|
|
|
|
return $allocations;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* 获取机台运行时间
|
|
|
*/
|
|
|
@@ -715,12 +764,16 @@ class UnifiedCostCalculationService
|
|
|
float $amount,
|
|
|
array $machineHours
|
|
|
): void {
|
|
|
- if ($subject === '待分摊总额') {
|
|
|
- $this->allocateByFloor($allocations, $amount, $machineHours);
|
|
|
- } elseif (in_array($subject, ['锅炉', '热水锅炉'])) {
|
|
|
- $this->allocateToRollCoater($allocations, $subject, $amount, $machineHours);
|
|
|
- } else {
|
|
|
- $this->allocateGlobally($allocations, $subject, $amount, $machineHours);
|
|
|
+ try {
|
|
|
+ if ($subject === '待分摊总额') {
|
|
|
+ $this->allocateByFloor($allocations, $amount, $machineHours);
|
|
|
+ } elseif (in_array($subject, ['锅炉', '热水锅炉'])) {
|
|
|
+ $this->allocateToRollCoater($allocations, $subject, $amount, $machineHours);
|
|
|
+ } else {
|
|
|
+ $this->allocateGlobally($allocations, $subject, $amount, $machineHours);
|
|
|
+ }
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error("按科目分摊时出错 (科目: {$subject}): " . $e->getMessage());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -928,13 +981,23 @@ class UnifiedCostCalculationService
|
|
|
$now = date('Y-m-d H:i:s');
|
|
|
|
|
|
foreach ($allocations as $machine => $subjects) {
|
|
|
+ if (!is_string($machine) && !is_numeric($machine)) {
|
|
|
+ Log::warning("无效的机台标识: " . print_r($machine, true));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
foreach ($subjects as $subject => $amount) {
|
|
|
+ if (!is_string($subject)) {
|
|
|
+ Log::warning("无效的科目名称: " . print_r($subject, true));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
$this->allocationFactors[] = [
|
|
|
'Sys_ny' => $month,
|
|
|
'科目名称' => $subject,
|
|
|
- '设备编号' => $machine,
|
|
|
+ '设备编号' => (string)$machine,
|
|
|
'分摊系数' => 1,
|
|
|
- '分摊金额' => $amount,
|
|
|
+ '分摊金额' => floatval($amount),
|
|
|
'Sys_id' => $sysId,
|
|
|
'Sys_rq' => $now,
|
|
|
];
|
|
|
@@ -1172,6 +1235,9 @@ class UnifiedCostCalculationService
|
|
|
{
|
|
|
Log::error("统一成本核算失败", [
|
|
|
'message' => $e->getMessage(),
|
|
|
+ 'code' => $e->getCode(),
|
|
|
+ 'file' => $e->getFile(),
|
|
|
+ 'line' => $e->getLine(),
|
|
|
'trace' => $e->getTraceAsString()
|
|
|
]);
|
|
|
}
|