CaiWuXiTong/app/Models/Business/FundForecast.php

226 lines
9.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Models\Business;
use App\Abstracts\Model;
class FundForecast extends Model
{
protected $table = 'business_fund_forecast';
public const BALANCE_FIELDS = [
'balance_bank', 'balance_jd', 'balance_douyin', 'balance_dewu',
'balance_taobao_alipay', 'balance_wechat',
];
public const INCOME_FIELDS = [
'income_jd', 'income_douyin', 'income_dewu', 'income_taobao_alipay',
'income_goods_payment', 'income_other',
];
public const EXPENSE_FIELDS = [
'expense_supplier_goods', 'expense_courier', 'expense_paper_lamination',
'expense_edge_band', 'expense_daily_reimbursement', 'expense_taobao_red_packet',
'expense_board', 'expense_store_top_up', 'expense_planting', 'expense_salary',
'expense_tax', 'expense_store_spend',
];
public const SUMMARY_FIELDS = [
'previous_month_balance', 'forecast_month_income', 'forecast_month_expense',
'gap_surplus', 'has_gap',
];
public const PAGE_FIELDS = [
'budget_month', 'company_name', 'region', 'report_status',
...self::BALANCE_FIELDS,
...self::INCOME_FIELDS,
...self::EXPENSE_FIELDS,
...self::SUMMARY_FIELDS,
];
protected $fillable = [
'company_id',
...self::PAGE_FIELDS,
// Legacy fields remain fillable so old records and rollback exports stay compatible.
'actual_month', 'store_balance_budget', 'store_balance_actual', 'bank_balance_budget',
'bank_balance_actual', 'other_balance_budget', 'other_balance_actual',
'expected_monthly_return_budget', 'expected_monthly_return_actual',
'income_total_budget', 'income_total_actual', 'prior_unpaid_budget',
'prior_unpaid_actual', 'advance_budget', 'advance_actual', 'supplier_budget',
'supplier_actual', 'spot_settlement_budget', 'spot_settlement_actual',
'courier_budget', 'courier_actual', 'paper_factory_budget', 'paper_factory_actual',
'edge_band_budget', 'edge_band_actual', 'board_budget', 'board_actual',
'salary_budget', 'salary_actual', 'daily_expense_budget', 'daily_expense_actual',
'planting_budget', 'planting_actual', 'red_packet_budget', 'red_packet_actual',
'corporate_deduction_budget', 'corporate_deduction_actual',
'expense_total_budget', 'expense_total_actual', 'bank_reservation',
'net_balance_budget', 'net_balance_actual',
];
protected $attributes = [
'report_status' => '待填报',
];
protected $casts = [
'company_id' => 'integer',
'has_gap' => 'boolean',
'balance_bank' => 'decimal:2',
'balance_jd' => 'decimal:2',
'balance_douyin' => 'decimal:2',
'balance_dewu' => 'decimal:2',
'balance_taobao_alipay' => 'decimal:2',
'balance_wechat' => 'decimal:2',
'income_jd' => 'decimal:2',
'income_douyin' => 'decimal:2',
'income_dewu' => 'decimal:2',
'income_taobao_alipay' => 'decimal:2',
'income_goods_payment' => 'decimal:2',
'income_other' => 'decimal:2',
'expense_supplier_goods' => 'decimal:2',
'expense_courier' => 'decimal:2',
'expense_paper_lamination' => 'decimal:2',
'expense_edge_band' => 'decimal:2',
'expense_daily_reimbursement' => 'decimal:2',
'expense_taobao_red_packet' => 'decimal:2',
'expense_board' => 'decimal:2',
'expense_store_top_up' => 'decimal:2',
'expense_planting' => 'decimal:2',
'expense_salary' => 'decimal:2',
'expense_tax' => 'decimal:2',
'expense_store_spend' => 'decimal:2',
'previous_month_balance' => 'decimal:2',
'forecast_month_income' => 'decimal:2',
'forecast_month_expense' => 'decimal:2',
'gap_surplus' => 'decimal:2',
];
protected static function booted(): void
{
static::creating(function (self $forecast): void {
if (empty($forecast->company_id)) {
$forecast->company_id = company_id() ?: 1;
}
});
static::saving(function (self $forecast): void {
$balance = self::sumFields($forecast, self::BALANCE_FIELDS);
$income = self::sumFields($forecast, self::INCOME_FIELDS);
$expense = self::sumFields($forecast, self::EXPENSE_FIELDS);
$gap = round($balance + $income - $expense, 2);
$forecast->previous_month_balance = $balance;
$forecast->forecast_month_income = $income;
$forecast->forecast_month_expense = $expense;
$forecast->gap_surplus = $gap;
$forecast->has_gap = $gap < 0;
});
}
private static function sumFields(self $forecast, array $fields): float
{
return array_reduce(
$fields,
fn (float $sum, string $field): float => round($sum + round((float) ($forecast->{$field} ?? 0), 2), 2),
0.0,
);
}
public static function columnLabels(): array
{
return [
'company_name' => '公司名称',
'region' => '所属区域',
'report_status' => '填报状态',
'budget_month' => '预算月份',
'actual_month' => '实际月份',
'store_balance_budget' => '店铺余额(预算)',
'store_balance_actual' => '店铺余额(实际)',
'bank_balance_budget' => '银行余额(预算)',
'bank_balance_actual' => '银行余额(实际)',
'other_balance_budget' => '其他余额(预算)',
'other_balance_actual' => '其他余额(实际)',
'expected_monthly_return_budget' => '预计回款(预算)',
'expected_monthly_return_actual' => '预计回款(实际)',
'income_total_budget' => '收入合计(预算)',
'income_total_actual' => '收入合计(实际)',
'prior_unpaid_budget' => '往期未付(预算)',
'prior_unpaid_actual' => '往期未付(实际)',
'advance_budget' => '借支(预算)',
'advance_actual' => '借支(实际)',
'supplier_budget' => '供应商(预算)',
'supplier_actual' => '供应商(实际)',
'spot_settlement_budget' => '现结(预算)',
'spot_settlement_actual' => '现结(实际)',
'courier_budget' => '快递(预算)',
'courier_actual' => '快递(实际)',
'paper_factory_budget' => '纸厂压贴(预算)',
'paper_factory_actual' => '纸厂压贴(实际)',
'edge_band_budget' => '封边条(预算)',
'edge_band_actual' => '封边条(实际)',
'board_budget' => '板材(预算)',
'board_actual' => '板材(实际)',
'salary_budget' => '工资(预算)',
'salary_actual' => '工资(实际)',
'daily_expense_budget' => '日常费用(预算)',
'daily_expense_actual' => '日常费用(实际)',
'planting_budget' => '种菜(预算)',
'planting_actual' => '种菜(实际)',
'red_packet_budget' => '红包(预算)',
'red_packet_actual' => '红包(实际)',
'corporate_deduction_budget' => '对公扣款(预算)',
'corporate_deduction_actual' => '对公扣款(实际)',
'expense_total_budget' => '支出合计(预算)',
'expense_total_actual' => '支出合计(实际)',
'bank_reservation' => '银行预留',
'net_balance_budget' => '净结余(预算)',
'net_balance_actual' => '净结余(实际)',
'balance_bank' => '银行',
'balance_jd' => '京东',
'balance_douyin' => '抖音',
'balance_dewu' => '得物',
'balance_taobao_alipay' => '淘系支付宝',
'balance_wechat' => '微信',
'income_jd' => '京东',
'income_douyin' => '抖音',
'income_dewu' => '得物',
'income_taobao_alipay' => '淘系支付宝',
'income_goods_payment' => '货款',
'income_other' => '其他收入',
'expense_supplier_goods' => '供应商货款',
'expense_courier' => '快递款',
'expense_paper_lamination' => '纸厂压贴',
'expense_edge_band' => '封边条',
'expense_daily_reimbursement' => '日常报销',
'expense_taobao_red_packet' => '淘宝红包',
'expense_board' => '板材',
'expense_store_top_up' => '店铺充值',
'expense_planting' => '种菜',
'expense_salary' => '工资',
'expense_tax' => '税金',
'expense_store_spend' => '店铺花费(暂估10%)',
'previous_month_balance' => '上月末总余额',
'forecast_month_income' => '预测本月收入',
'forecast_month_expense' => '预测本月支付',
'gap_surplus' => '缺口/盈余',
'has_gap' => '是否有缺口',
];
}
public static function fieldTypes(): array
{
return array_replace(
array_fill_keys([
...self::BALANCE_FIELDS,
...self::INCOME_FIELDS,
...self::EXPENSE_FIELDS,
'previous_month_balance', 'forecast_month_income',
'forecast_month_expense', 'gap_surplus',
], 'currency'),
[
'report_status' => 'select',
'has_gap' => 'boolean',
],
);
}
}