mirror of
https://gitee.com/ShopeX/OMS
synced 2026-04-05 14:45:33 +08:00
1. 【新增】售后单售后原因类型支持搜索
2. 【新增】手工创建订单折扣可输入正数 3. 【优化】盘点申请单确认 4. 【修复】采购退货单模拟出库失败问题 5. 【新增】订单金额客户实付与结算金额 6. 【优化】仓库发货统计报表物料名称显示 7. 【优化】自有仓储虚拟发货逻辑 8. 【修复】基础物料分类管理问题
This commit is contained in:
@@ -35,8 +35,8 @@ class financebase_ctl_admin_expenses_rule extends desktop_controller {
|
||||
'title'=>'费用拆分规则',
|
||||
'use_buildin_set_tag'=>false,
|
||||
'use_buildin_filter'=>false,
|
||||
'use_buildin_selectrow'=>false,
|
||||
'use_buildin_export'=>false,
|
||||
'use_buildin_selectrow'=>true,
|
||||
'use_buildin_export'=>true,
|
||||
'use_buildin_import'=>false,
|
||||
'use_buildin_recycle'=>false,
|
||||
'finder_cols'=>'column_edit,bill_category,split_type,split_rule,split_last_modify',
|
||||
|
||||
@@ -73,11 +73,12 @@ class financebase_ctl_admin_expenses_splititem extends desktop_controller {
|
||||
$modelName = 'financebase_mdl_expenses_split';
|
||||
if($view == 3) {
|
||||
$params['base_filter'] = array('split_status' => ['1','2']);
|
||||
} else if($view == 0) {
|
||||
}
|
||||
if($view == 0) {
|
||||
$params['actions'][] = array(
|
||||
'label' => '导入对账状态',
|
||||
'href' => 'index.php?app=financebase&ctl=admin_expenses_splititem&act=importReconciled',
|
||||
'target' => "dialog::{width:500,height:200,title:'导入对账状态'}",
|
||||
'label' => '导入记账',
|
||||
'href' => $this->url.'&act=execlImportDailog&p[0]=expenses_split',
|
||||
'target' => 'dialog::{width:500,height:300,title:\'导入记账\'}',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -181,74 +182,4 @@ class financebase_ctl_admin_expenses_splititem extends desktop_controller {
|
||||
echo json_encode($retArr),'ok.';exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入对账状态页面
|
||||
*/
|
||||
public function importReconciled()
|
||||
{
|
||||
$this->display('admin/expenses/import_reconciled.html');
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理导入对账状态
|
||||
*/
|
||||
public function doImportReconciled()
|
||||
{
|
||||
$this->begin('index.php?app=financebase&ctl=admin_expenses_splititem&act=index');
|
||||
|
||||
if (!$_FILES['import_file']['tmp_name']) {
|
||||
$this->end(false, '请选择要导入的文件');
|
||||
}
|
||||
|
||||
$file = fopen($_FILES['import_file']['tmp_name'], 'r');
|
||||
if (!$file) {
|
||||
$this->end(false, '文件打开失败');
|
||||
}
|
||||
|
||||
// 读取标题行
|
||||
$header = fgetcsv($file);
|
||||
if (!$header || !in_array('id', $header) || !in_array('是否对账', $header)) {
|
||||
fclose($file);
|
||||
$this->end(false, '文件格式不正确,必须包含"id"和"是否对账"列');
|
||||
}
|
||||
|
||||
// 获取列的索引
|
||||
$idIndex = array_search('id', $header);
|
||||
$reconciledIndex = array_search('是否对账', $header);
|
||||
|
||||
$mdl = app::get('financebase')->model('expenses_split');
|
||||
$success = 0;
|
||||
$error = 0;
|
||||
|
||||
while (($data = fgetcsv($file)) !== false) {
|
||||
$id = $data[$idIndex];
|
||||
$isReconciled = $data[$reconciledIndex];
|
||||
|
||||
// 验证数据
|
||||
if (!$id || !in_array($isReconciled, ['是', '否'])) {
|
||||
$error++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 更新数据
|
||||
$result = $mdl->update(
|
||||
['confirm_status' => $isReconciled === '是' ? '1' : '0'],
|
||||
['id' => $id]
|
||||
);
|
||||
|
||||
if ($result) {
|
||||
$success++;
|
||||
} else {
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
|
||||
fclose($file);
|
||||
|
||||
if ($success > 0) {
|
||||
$this->end(true, sprintf('导入完成:成功 %d 条,失败 %d 条', $success, $error));
|
||||
} else {
|
||||
$this->end(false, '导入失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,557 @@
|
||||
<?php
|
||||
/**
|
||||
* 会计科目控制层
|
||||
*
|
||||
* @author 334395174@qq.com
|
||||
* @version 0.1
|
||||
*/
|
||||
|
||||
class financebase_ctl_admin_shop_settlement_account_chart extends desktop_controller
|
||||
{
|
||||
|
||||
/**
|
||||
* 会计科目列表分栏菜单
|
||||
*
|
||||
* @param Null
|
||||
* @return Array
|
||||
*/
|
||||
public function _views()
|
||||
{
|
||||
#不是列表时隐藏Tab
|
||||
if ($_GET['act'] != 'index') {
|
||||
return array();
|
||||
}
|
||||
|
||||
$accountChartObj = app::get('financebase')->model('account_chart');
|
||||
|
||||
$sub_menu = array(
|
||||
0 => array('label' => app::get('base')->_('有效'), 'filter' => array('disabled' => 'false'), 'optional' => false),
|
||||
1 => array('label' => app::get('base')->_('无效'), 'filter' => array('disabled' => 'true'), 'optional' => false),
|
||||
// 2 => array('label' => app::get('base')->_('全部'), 'optional' => false),
|
||||
);
|
||||
|
||||
foreach ($sub_menu as $k => $v) {
|
||||
$sub_menu[$k]['filter'] = $v['filter'] ? $v['filter'] : null;
|
||||
$sub_menu[$k]['addon'] = $accountChartObj->count($v['filter']);
|
||||
$sub_menu[$k]['href'] = 'index.php?app=financebase&ctl=admin_shop_settlement_account_chart&act=index&view=' . $k;
|
||||
}
|
||||
|
||||
return $sub_menu;
|
||||
}
|
||||
|
||||
// 会计科目列表
|
||||
public function index()
|
||||
{
|
||||
// 根据view设置base_filter
|
||||
$base_filter = array();
|
||||
$view = isset($_GET['view']) ? intval($_GET['view']) : 0;
|
||||
|
||||
if ($view == 0) {
|
||||
// 有效
|
||||
$base_filter = array('disabled' => 'false');
|
||||
} elseif ($view == 1) {
|
||||
// 无效
|
||||
$base_filter = array('disabled' => 'true');
|
||||
}
|
||||
// view == 2 是全部,不需要设置base_filter
|
||||
|
||||
$actions = array();
|
||||
|
||||
// 新增按钮权限控制
|
||||
if (kernel::single('desktop_user')->has_permission('shop_settlement_account_chart_add')) {
|
||||
$actions[] = array(
|
||||
'label'=>'新增',
|
||||
'href'=>'index.php?app=financebase&ctl=admin_shop_settlement_account_chart&act=setAccount&p[0]=0&singlepage=false&finder_id='.$_GET['finder_id'],
|
||||
'target'=>'dialog::{width:550,height:520,resizeable:false,title:\'新增会计科目\'}'
|
||||
);
|
||||
}
|
||||
|
||||
// 置为无效按钮权限控制 - 只在有效tab中显示
|
||||
if (kernel::single('desktop_user')->has_permission('shop_settlement_account_chart_delete') && $view == 0) {
|
||||
$actions[] = array(
|
||||
'label' => '置为无效',
|
||||
'confirm' => '你确定要将选中的会计科目置为无效吗?',
|
||||
'submit' => 'index.php?app=financebase&ctl=admin_shop_settlement_account_chart&act=disableAccount',
|
||||
'target' => 'refresh'
|
||||
);
|
||||
}
|
||||
|
||||
// 恢复按钮权限控制 - 只在无效tab中显示
|
||||
if (kernel::single('desktop_user')->has_permission('shop_settlement_account_chart_restore') && $view == 1) {
|
||||
$actions[] = array(
|
||||
'label' => '置为有效',
|
||||
'confirm' => '你确定要将选中的会计科目置为有效吗?',
|
||||
'submit' => 'index.php?app=financebase&ctl=admin_shop_settlement_account_chart&act=restoreAccount',
|
||||
'target' => 'refresh'
|
||||
);
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'title'=>'会计科目设置',
|
||||
'actions' => $actions,
|
||||
'base_filter' => $base_filter,
|
||||
'use_buildin_set_tag'=>false,
|
||||
'use_buildin_recycle'=>false,
|
||||
'use_buildin_filter'=>false,
|
||||
'use_buildin_export'=> false,
|
||||
'use_buildin_import'=> false,
|
||||
'orderBy'=>'id',
|
||||
);
|
||||
|
||||
$this->finder('financebase_mdl_account_chart',$params);
|
||||
}
|
||||
|
||||
// 设置会计科目
|
||||
public function setAccount($id=0)
|
||||
{
|
||||
// 检查权限
|
||||
if ($id > 0) {
|
||||
// 编辑模式
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_account_chart_edit')) {
|
||||
$this->splash('error', null, '您没有编辑会计科目的权限');
|
||||
}
|
||||
} else {
|
||||
// 新增模式
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_account_chart_add')) {
|
||||
$this->splash('error', null, '您没有新增会计科目的权限');
|
||||
}
|
||||
}
|
||||
|
||||
$account_info = array('id'=>$id);
|
||||
$oAccount = app::get('financebase')->model("account_chart");
|
||||
// 检查已存在的应用场景
|
||||
$existing_categories = array();
|
||||
if($id){
|
||||
$account_info=$oAccount->db_dump(array('id'=>$id));
|
||||
|
||||
// 编辑模式:排除当前记录
|
||||
$platform_exists = $oAccount->count(array('account_category' => 'platform_amount', 'id|noequal' => $id));
|
||||
$actually_exists = $oAccount->count(array('account_category' => 'actually_amount', 'id|noequal' => $id));
|
||||
$refund_platform_exists = $oAccount->count(array('account_category' => 'refundplatform_amount', 'id|noequal' => $id));
|
||||
$refund_actually_exists = $oAccount->count(array('account_category' => 'refundactually_amount', 'id|noequal' => $id));
|
||||
} else {
|
||||
// 新增模式:检查所有记录
|
||||
$platform_exists = $oAccount->count(array('account_category' => 'platform_amount'));
|
||||
$actually_exists = $oAccount->count(array('account_category' => 'actually_amount'));
|
||||
$refund_platform_exists = $oAccount->count(array('account_category' => 'refundplatform_amount'));
|
||||
$refund_actually_exists = $oAccount->count(array('account_category' => 'refundactually_amount'));
|
||||
}
|
||||
|
||||
if($platform_exists > 0) {
|
||||
$existing_categories[] = 'platform_amount';
|
||||
}
|
||||
if($actually_exists > 0) {
|
||||
$existing_categories[] = 'actually_amount';
|
||||
}
|
||||
if($refund_platform_exists > 0) {
|
||||
$existing_categories[] = 'refundplatform_amount';
|
||||
}
|
||||
if($refund_actually_exists > 0) {
|
||||
$existing_categories[] = 'refundactually_amount';
|
||||
}
|
||||
|
||||
$this->pagedata['account_info'] = $account_info;
|
||||
$this->pagedata['existing_categories'] = $existing_categories;
|
||||
$this->display("admin/account/chart.html");
|
||||
}
|
||||
|
||||
// 保存会计科目
|
||||
public function saveAccount()
|
||||
{
|
||||
$this->begin('index.php?app=financebase&ctl=admin_shop_settlement_account_chart&act=index');
|
||||
|
||||
// 检查权限
|
||||
$is_edit = !empty($_POST['id']);
|
||||
if ($is_edit) {
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_account_chart_edit')) {
|
||||
$this->end(false, '您没有编辑会计科目的权限');
|
||||
}
|
||||
} else {
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_account_chart_add')) {
|
||||
$this->end(false, '您没有新增会计科目的权限');
|
||||
}
|
||||
}
|
||||
|
||||
$oAccount = app::get('financebase')->model("account_chart");
|
||||
$data = array();
|
||||
|
||||
$data['id'] = intval($_POST['id']);
|
||||
|
||||
// 获取原始数据用于日志记录(仅编辑时需要)
|
||||
$existing = null;
|
||||
if ($is_edit) {
|
||||
$existing = $oAccount->dump(array('id' => $data['id']));
|
||||
}
|
||||
|
||||
// 生成会计科目编码的逻辑
|
||||
// 新增时自动生成,编辑时如果现有数据没有编码也生成
|
||||
$need_generate_code = !$is_edit || empty($existing['account_code']);
|
||||
|
||||
if ($need_generate_code) {
|
||||
// 获取最后一条数据的account_code
|
||||
$sql = "SELECT account_code FROM sdb_financebase_account_chart WHERE disabled = 'false' ORDER BY account_code DESC";
|
||||
$last_account = $oAccount->db->selectrow($sql);
|
||||
|
||||
if ($last_account && !empty($last_account['account_code'])) {
|
||||
// 提取数字部分并加1
|
||||
$last_num = intval(substr($last_account['account_code'], 4));
|
||||
$new_num = $last_num + 1;
|
||||
$data['account_code'] = 'KJKM' . str_pad($new_num, 3, '0', STR_PAD_LEFT);
|
||||
} else {
|
||||
// 第一条数据
|
||||
$data['account_code'] = 'KJKM001';
|
||||
}
|
||||
}
|
||||
|
||||
$data['account'] = htmlspecialchars(trim($_POST['account']));
|
||||
$data['description'] = htmlspecialchars(trim($_POST['description']));
|
||||
$data['postingkey'] = htmlspecialchars(trim($_POST['postingkey']));
|
||||
$data['customer'] = htmlspecialchars(trim($_POST['customer']));
|
||||
$data['costcenter'] = htmlspecialchars(trim($_POST['costcenter']));
|
||||
|
||||
// 验证会计科目和客户至少填写一项
|
||||
if (empty($data['account']) && empty($data['customer'])) {
|
||||
$this->end(false, "会计科目 和 客户 至少填写一项");
|
||||
}
|
||||
if (($_POST['tax_rate'])!=='') {
|
||||
$data['tax_rate'] = $_POST['tax_rate'];
|
||||
}
|
||||
$data['tax_account'] = htmlspecialchars(trim($_POST['tax_account']));
|
||||
$data['account_category'] = trim($_POST['account_category']);
|
||||
$data['reason_code'] = trim($_POST['reason_code']);
|
||||
// 验证税率和税率会计科目的关联关系
|
||||
if (!empty($data['tax_rate']) && $data['tax_rate']>0 && empty($data['tax_account'])) {
|
||||
$this->end(false, "如果有税率,税率会计科目为必填项");
|
||||
}
|
||||
|
||||
// 编辑模式:如果设置了应用场景,需要检查该会计科目是否已被使用
|
||||
if ($is_edit && !empty($data['account_category']) && in_array($data['account_category'], array('platform_amount', 'actually_amount', 'refundplatform_amount', 'refundactually_amount'))) {
|
||||
// 检查收支分类是否使用了该科目
|
||||
$oRules = app::get('financebase')->model("bill_category_rules");
|
||||
$rules_used = $oRules->getList('bill_category', array(
|
||||
'account_id_plus' => $data['id']
|
||||
));
|
||||
if(empty($rules_used)){
|
||||
$rules_used = $oRules->getList('bill_category', array(
|
||||
'account_id_minus' => $data['id']
|
||||
));
|
||||
}
|
||||
|
||||
if(!empty($rules_used)){
|
||||
$used_categories = array_column($rules_used, 'bill_category');
|
||||
$this->end(false, "会计科目【{$data['account']}】已被收支分类【" . implode('、', $used_categories) . "】使用,不得设置应用场景");
|
||||
}
|
||||
|
||||
// 检查差异类型是否使用了该科目
|
||||
$oGap = app::get('financebase')->model("gap");
|
||||
$gap_used = $oGap->getList('gap_name', array(
|
||||
'account_id_plus' => $data['id']
|
||||
));
|
||||
if(empty($gap_used)){
|
||||
$gap_used = $oGap->getList('gap_name', array(
|
||||
'account_id_minus' => $data['id']
|
||||
));
|
||||
}
|
||||
|
||||
if(!empty($gap_used)){
|
||||
$used_gaps = array_column($gap_used, 'gap_name');
|
||||
$this->end(false, "会计科目【{$data['account']}】已被差异类型【" . implode('、', $used_gaps) . "】使用,不得设置应用场景");
|
||||
}
|
||||
}
|
||||
|
||||
// 验证应收分类的唯一性
|
||||
if (!empty($data['account_category']) && in_array($data['account_category'], array('platform_amount', 'actually_amount', 'refundplatform_amount', 'refundactually_amount'))) {
|
||||
$filter = array('account_category' => $data['account_category']);
|
||||
if ($data['id']) {
|
||||
$filter['id|noequal'] = $data['id'];
|
||||
}
|
||||
if ($oAccount->count($filter) > 0) {
|
||||
$category_names = array(
|
||||
'platform_amount' => '平台承担',
|
||||
'actually_amount' => '客户实付',
|
||||
'refundplatform_amount' => '平台补贴退',
|
||||
'refundactually_amount' => '客户应退'
|
||||
);
|
||||
$category_name = $category_names[$data['account_category']];
|
||||
$this->end(false, $category_name . "只能有一条数据");
|
||||
}
|
||||
}
|
||||
|
||||
// 注释:已去掉会计科目+记账码组合的唯一性判断
|
||||
// 允许相同的会计科目+记账码组合存在
|
||||
|
||||
if($oAccount->save($data))
|
||||
{
|
||||
// 记录操作日志和快照
|
||||
$action = $is_edit ? 'edit' : 'add';
|
||||
$this->_recordLog($action, $data['id'], $data, $existing);
|
||||
$this->end(true, app::get('base')->_('保存成功'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->end(false, app::get('base')->_('保存失败'));
|
||||
}
|
||||
}
|
||||
|
||||
// 置为无效会计科目
|
||||
public function disableAccount()
|
||||
{
|
||||
$this->begin('index.php?app=financebase&ctl=admin_shop_settlement_account_chart&act=index');
|
||||
|
||||
// 检查置为无效权限
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_account_chart_delete')) {
|
||||
$this->end(false, '您没有置为无效会计科目的权限');
|
||||
}
|
||||
|
||||
if($_POST['isSelectedAll'] == '_ALL_'){
|
||||
$this->end(false,'不支持全选置为无效');
|
||||
}
|
||||
|
||||
if(empty($_POST['id'])){
|
||||
$this->end(false,'请选择要置为无效的会计科目');
|
||||
}
|
||||
|
||||
$oAccount = app::get('financebase')->model("account_chart");
|
||||
$oRules = app::get('financebase')->model("bill_category_rules");
|
||||
$oGap = app::get('financebase')->model("gap");
|
||||
|
||||
foreach($_POST['id'] as $account_id){
|
||||
if($account_id){
|
||||
// 获取会计科目信息
|
||||
$account_info = $oAccount->dump(array('id'=>$account_id), 'account');
|
||||
if(!$account_info){
|
||||
$this->end(false, '会计科目不存在');
|
||||
}
|
||||
|
||||
$account_name = $account_info['account'];
|
||||
|
||||
// 检查收支分类是否使用了该科目
|
||||
$rules_used = $oRules->getList('bill_category', array(
|
||||
'account_id_plus' => $account_id
|
||||
));
|
||||
if(empty($rules_used)){
|
||||
$rules_used = $oRules->getList('bill_category', array(
|
||||
'account_id_minus' => $account_id
|
||||
));
|
||||
}
|
||||
|
||||
if(!empty($rules_used)){
|
||||
$used_categories = array_column($rules_used, 'bill_category');
|
||||
$this->end(false, "会计科目【{$account_name}】已被收支分类【" . implode('、', $used_categories) . "】使用,无法删除");
|
||||
}
|
||||
|
||||
// 检查差异类型是否使用了该科目
|
||||
$gap_used = $oGap->getList('gap_name', array(
|
||||
'account_id_plus' => $account_id
|
||||
));
|
||||
if(empty($gap_used)){
|
||||
$gap_used = $oGap->getList('gap_name', array(
|
||||
'account_id_minus' => $account_id
|
||||
));
|
||||
}
|
||||
|
||||
if(!empty($gap_used)){
|
||||
$used_gaps = array_column($gap_used, 'gap_name');
|
||||
$this->end(false, "会计科目【{$account_name}】已被差异类型【" . implode('、', $used_gaps) . "】使用,无法置为无效");
|
||||
}
|
||||
|
||||
// 执行软删除 - 将disabled设置为true
|
||||
if(!$oAccount->update(array('disabled' => 'true'), array('id'=>$account_id))){
|
||||
$this->end(false, "置为无效会计科目【{$account_name}】失败");
|
||||
}
|
||||
|
||||
// 记录操作日志
|
||||
$this->_recordLog('delete', $account_id);
|
||||
}
|
||||
}
|
||||
|
||||
$this->end(true, '置为无效成功');
|
||||
}
|
||||
|
||||
// 恢复会计科目
|
||||
public function restoreAccount()
|
||||
{
|
||||
$this->begin('index.php?app=financebase&ctl=admin_shop_settlement_account_chart&act=index');
|
||||
|
||||
// 检查恢复权限
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_account_chart_restore')) {
|
||||
$this->end(false, '您没有恢复会计科目的权限');
|
||||
}
|
||||
|
||||
if($_POST['isSelectedAll'] == '_ALL_'){
|
||||
$this->end(false,'不支持全选恢复');
|
||||
}
|
||||
|
||||
if(empty($_POST['id'])){
|
||||
$this->end(false,'请选择要恢复的会计科目');
|
||||
}
|
||||
|
||||
$oAccount = app::get('financebase')->model("account_chart");
|
||||
|
||||
foreach($_POST['id'] as $account_id){
|
||||
if($account_id){
|
||||
// 获取会计科目信息
|
||||
$account_info = $oAccount->dump(array('id'=>$account_id), 'account');
|
||||
if(!$account_info){
|
||||
$this->end(false, '会计科目不存在');
|
||||
}
|
||||
|
||||
$account_name = $account_info['account'];
|
||||
|
||||
// 执行恢复 - 将disabled设置为false
|
||||
if(!$oAccount->update(array('disabled' => 'false'), array('id'=>$account_id))){
|
||||
$this->end(false, "恢复会计科目【{$account_name}】失败");
|
||||
}
|
||||
|
||||
// 记录操作日志
|
||||
$this->_recordLog('restore', $account_id);
|
||||
}
|
||||
}
|
||||
|
||||
$this->end(true, '置为有效成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录操作日志
|
||||
*
|
||||
* @param string $action 操作类型:add/edit/delete/restore
|
||||
* @param int $account_id 会计科目ID
|
||||
* @param array $data 新数据(编辑时需要)
|
||||
* @param array $existing 原始数据(编辑时需要)
|
||||
*/
|
||||
private function _recordLog($action, $account_id, $data = null, $existing = null)
|
||||
{
|
||||
$omeLogMdl = app::get('ome')->model('operation_log');
|
||||
|
||||
// 根据操作类型设置日志参数
|
||||
switch ($action) {
|
||||
case 'add':
|
||||
$log_key = 'account_chart_add@financebase';
|
||||
$memo = '新增会计科目';
|
||||
break;
|
||||
case 'edit':
|
||||
$log_key = 'account_chart_edit@financebase';
|
||||
$memo = '编辑会计科目';
|
||||
break;
|
||||
case 'delete':
|
||||
$log_key = 'account_chart_delete@financebase';
|
||||
$memo = '置为无效会计科目';
|
||||
break;
|
||||
case 'restore':
|
||||
$log_key = 'account_chart_restore@financebase';
|
||||
$memo = '恢复会计科目';
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// 记录操作日志
|
||||
$log_id = $omeLogMdl->write_log($log_key, $account_id, $memo);
|
||||
|
||||
// 生成操作快照(只有编辑时才存储)
|
||||
if ($log_id && $action == 'edit' && $existing && $data) {
|
||||
$shootMdl = app::get('ome')->model('operation_log_snapshoot');
|
||||
$snapshoot = json_encode($existing, JSON_UNESCAPED_UNICODE);
|
||||
$updated = json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
$tmp = [
|
||||
'log_id' => $log_id,
|
||||
'snapshoot' => $snapshoot,
|
||||
'updated' => $updated
|
||||
];
|
||||
$shootMdl->insert($tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看快照
|
||||
*/
|
||||
public function show_history($log_id)
|
||||
{
|
||||
$logSnapshootMdl = app::get('ome')->model('operation_log_snapshoot');
|
||||
$log = $logSnapshootMdl->db_dump(['log_id' => $log_id]);
|
||||
$row = json_decode($log['snapshoot'], 1);
|
||||
|
||||
if (!$row) {
|
||||
$this->splash('error', null, '快照数据不存在');
|
||||
}
|
||||
|
||||
// 对比数据差异
|
||||
$diff_data = array();
|
||||
if (!empty($log['updated'])) {
|
||||
$updated_data = json_decode($log['updated'], 1);
|
||||
$diff_data = $this->_compareAccountData($row, $updated_data);
|
||||
}
|
||||
|
||||
// 检查已存在的应用场景(用于显示当前状态)
|
||||
$existing_categories = array();
|
||||
$oAccount = app::get('financebase')->model("account_chart");
|
||||
$platform_exists = $oAccount->count(array('account_category' => 'platform_amount', 'id|noequal' => $row['id']));
|
||||
$actually_exists = $oAccount->count(array('account_category' => 'actually_amount', 'id|noequal' => $row['id']));
|
||||
$refund_platform_exists = $oAccount->count(array('account_category' => 'refundplatform_amount', 'id|noequal' => $row['id']));
|
||||
$refund_actually_exists = $oAccount->count(array('account_category' => 'refundactually_amount', 'id|noequal' => $row['id']));
|
||||
|
||||
if($platform_exists > 0) {
|
||||
$existing_categories[] = 'platform_amount';
|
||||
}
|
||||
if($actually_exists > 0) {
|
||||
$existing_categories[] = 'actually_amount';
|
||||
}
|
||||
if($refund_platform_exists > 0) {
|
||||
$existing_categories[] = 'refundplatform_amount';
|
||||
}
|
||||
if($refund_actually_exists > 0) {
|
||||
$existing_categories[] = 'refundactually_amount';
|
||||
}
|
||||
|
||||
$this->pagedata['account_info'] = $row;
|
||||
$this->pagedata['diff_data'] = $diff_data;
|
||||
$this->pagedata['existing_categories'] = $existing_categories;
|
||||
$this->pagedata['history'] = true;
|
||||
$this->singlepage("admin/account/chart.html");
|
||||
}
|
||||
|
||||
/**
|
||||
* 对比会计科目数据差异
|
||||
*/
|
||||
private function _compareAccountData($old_data, $new_data)
|
||||
{
|
||||
$diff_data = array();
|
||||
|
||||
// 需要对比的字段
|
||||
$compare_fields = array('account', 'description', 'postingkey', 'customer', 'costcenter', 'tax_rate', 'tax_account', 'account_category', 'reason_code');
|
||||
|
||||
foreach ($compare_fields as $field) {
|
||||
$old_value = isset($old_data[$field]) ? $old_data[$field] : '';
|
||||
$new_value = isset($new_data[$field]) ? $new_data[$field] : '';
|
||||
|
||||
// 特殊处理应收分类字段
|
||||
if ($field == 'account_category') {
|
||||
$category_names = array(
|
||||
'platform_amount' => '平台承担',
|
||||
'actually_amount' => '客户实付',
|
||||
'refundplatform_amount' => '平台补贴退',
|
||||
'refundactually_amount' => '客户应退'
|
||||
);
|
||||
|
||||
$old_value = isset($category_names[$old_value]) ? $category_names[$old_value] : ($old_value ?: '未设置');
|
||||
$new_value = isset($category_names[$new_value]) ? $category_names[$new_value] : ($new_value ?: '未设置');
|
||||
}
|
||||
|
||||
// 特殊处理税率字段
|
||||
if ($field == 'tax_rate') {
|
||||
$old_value = $old_value ?: '未设置';
|
||||
$new_value = $new_value ?: '未设置';
|
||||
}
|
||||
|
||||
// 只有有变化时才添加到diff_data
|
||||
if ($old_value != $new_value) {
|
||||
$diff_data[$field] = array(
|
||||
'old_value' => $old_value,
|
||||
'new_value' => $new_value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $diff_data;
|
||||
}
|
||||
}
|
||||
@@ -61,53 +61,187 @@ class financebase_ctl_admin_shop_settlement_bill extends desktop_controller
|
||||
kernel::single('financebase_base')->set_params($_POST)->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取平台配置(统一配置,一处修改,处处生效)
|
||||
*
|
||||
* 字段说明:
|
||||
* - name: 平台显示名称,用于卡片标题和弹层标题
|
||||
* - icon: 平台图标文字,显示在卡片中央
|
||||
* - shop_filter: 店铺筛选条件数组,用于筛选店铺列表
|
||||
* - 格式:array('shop_type' => array(...), 'business_type' => array(...))
|
||||
* - shop_type: 店铺类型数组,如 array('taobao','tmall')
|
||||
* - business_type: 业务类型数组(可选),如 array('maochao')
|
||||
* - 'all': 特殊值,表示支持所有店铺类型
|
||||
* - order: 排序权重,数值越小排序越靠前
|
||||
* - template_file: 模板文件配置
|
||||
* - 单个模板:字符串格式,如 'alipay.xlsx'
|
||||
* - 多个模板:数组格式,如 array('下载正向模版' => 'xxx.xlsx', '下载逆向模版' => 'yyy.xlsx')
|
||||
* - 数组格式时,key 为下载链接显示文字,value 为模板文件名
|
||||
* - template_fields: 模板字段说明(可选),显示在弹层顶部
|
||||
* - file_format: 支持的文件格式(可选),只配置括号内容,如 '.xls、 .xlsx'
|
||||
*/
|
||||
private function getPlatformConfig() {
|
||||
return array(
|
||||
'alipay' => array(
|
||||
'name' => '支付宝账单导入',
|
||||
'icon' => '支付宝',
|
||||
'shop_filter' => array('shop_type' => array('taobao','tmall')),
|
||||
'order' => '100',
|
||||
'template_file' => 'alipay.xlsx'
|
||||
),
|
||||
'jd' => array(
|
||||
'name' => '京东日账单导入',
|
||||
'icon' => '京东日账单',
|
||||
'shop_filter' => array('shop_type' => array('360buy')),
|
||||
'order' => '200',
|
||||
'template_file' => '360buy.xlsx'
|
||||
),
|
||||
'luban' => array(
|
||||
'name' => '抖音账单导入',
|
||||
'icon' => '抖音',
|
||||
'shop_filter' => array('shop_type' => array('luban')),
|
||||
'order' => '600',
|
||||
'template_file' => 'luban.xlsx'
|
||||
),
|
||||
'youzan' => array(
|
||||
'name' => '有赞账单导入',
|
||||
'icon' => '有赞',
|
||||
'shop_filter' => array('shop_type' => array('youzan')),
|
||||
'order' => '700',
|
||||
'template_file' => 'youzan.xlsx'
|
||||
),
|
||||
'pinduoduo' => array(
|
||||
'name' => '拼多多账单导入',
|
||||
'icon' => '拼多多',
|
||||
'shop_filter' => array('shop_type' => array('pinduoduo')),
|
||||
'order' => '800',
|
||||
'template_file' => 'pinduoduo.xlsx'
|
||||
),
|
||||
'wechatpay' => array(
|
||||
'name' => '微信账单导入',
|
||||
'icon' => '微信',
|
||||
'shop_filter' => array('shop_type' => array('wx','weixinshop','website','youzan')),
|
||||
'order' => '900',
|
||||
'template_file' => 'wechatpay.xlsx'
|
||||
),
|
||||
'wxpay' => array(
|
||||
'name' => '微信小店账单导入',
|
||||
'icon' => '微信小店',
|
||||
'shop_filter' => array('shop_type' => array('wx','youzan','wxshipin')),
|
||||
'order' => '1300',
|
||||
'template_file' => 'wxpay.xlsx'
|
||||
),
|
||||
'jdwallet' => array(
|
||||
'name' => '京东钱包导入',
|
||||
'icon' => '京东钱包',
|
||||
'shop_filter' => array('shop_type' => array('360buy')),
|
||||
'order' => '1400',
|
||||
'template_file' => 'jdwallet.xlsx',
|
||||
'template_fields' => '注意:文件必须包含"结算表"和"资金表"两个工作表',
|
||||
'file_format' => '.xls、 .xlsx',
|
||||
),
|
||||
'guobu' => array(
|
||||
'name' => '国补金额导入',
|
||||
'icon' => '国补',
|
||||
'shop_filter' => 'all', // 特殊处理,使用所有店铺类型
|
||||
'order' => '1500',
|
||||
'template_file' => 'guobu.xlsx',
|
||||
'template_fields' => '模板字段:订单号、国补金额、SKU、数量、账单日期',
|
||||
),
|
||||
'xhs' => array(
|
||||
'name' => '小红书账单导入',
|
||||
'icon' => '小红书',
|
||||
'shop_filter' => array('shop_type' => array('xhs')),
|
||||
'order' => '1600',
|
||||
'template_file' => 'xhs.xlsx'
|
||||
),
|
||||
'miaosuda' => array(
|
||||
'name' => '喵速达账单导入',
|
||||
'icon' => '喵速达',
|
||||
'shop_filter' => array('shop_type' => array('taobao'), 'business_type' => array('maochao')),
|
||||
'order' => '1700',
|
||||
'template_file' => 'miaosuda.xlsx'
|
||||
),
|
||||
'tmyp' => array(
|
||||
'name' => '天猫优品结算单导入',
|
||||
'icon' => '天猫优品',
|
||||
'shop_filter' => array('shop_type' => array('taobao'), 'tbbusiness_type' => array('B')),
|
||||
'order' => '1800',
|
||||
'template_file' => 'tianmaoyoupin.xlsx'
|
||||
),
|
||||
'jdecard' => array(
|
||||
'name' => '京东E卡结算单导入',
|
||||
'icon' => '京东E卡',
|
||||
'shop_filter' => array('shop_type' => array('360buy')),
|
||||
'order' => '1900',
|
||||
'template_file' => 'jdecard.xlsx'
|
||||
),
|
||||
'jdguobu' => array(
|
||||
'name' => '京东国补结算单导入',
|
||||
'icon' => '京东国补',
|
||||
'shop_filter' => array('shop_type' => array('360buy')),
|
||||
'order' => '2000',
|
||||
'template_file' => 'jdguobu.xlsx'
|
||||
),
|
||||
'weimobr' => array(
|
||||
'name' => '微盟零售账单导入',
|
||||
'icon' => '微盟零售',
|
||||
'shop_filter' => array('shop_type' => array('weimobr')),
|
||||
'order' => '2100',
|
||||
'template_file' => array(
|
||||
'下载正向模版' => 'weimobr/sales.xlsx',
|
||||
'下载逆向模版' => 'weimobr/refunds.xlsx'
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
//收支单导入 - 账单导入
|
||||
/**
|
||||
* bill_import
|
||||
* @return mixed 返回值
|
||||
*/
|
||||
public function bill_import(){
|
||||
// 显示tab
|
||||
$settingTabs = array(
|
||||
array('name' => '支付宝账单导入', 'file_name' => 'admin/bill/import/alipay.html', 'type' => 'alipay','order'=>'100'),
|
||||
array('name' => '京东日账单导入', 'file_name' => 'admin/bill/import/360buy.html', 'type' => 'jd','order'=>'200'),
|
||||
array('name' => '抖音账单导入', 'file_name' => 'admin/bill/import/luban.html', 'type' => 'luban','order'=>'600'),
|
||||
array('name' => '有赞账单导入', 'file_name' => 'admin/bill/import/youzan.html', 'type' => 'youzan','order'=>'700'),
|
||||
array('name' => '拼多多账单导入', 'file_name' => 'admin/bill/import/pinduoduo.html', 'type' => 'pinduoduo','order'=>'800'),
|
||||
array('name' => '微信账单导入', 'file_name' => 'admin/bill/import/wechatpay.html', 'type' => 'wechatpay','order'=>'900'),
|
||||
// array('name' => '一号店账单导入', 'file_name' => 'bill/import/yihaodian.html', 'app' => 'finance','order'=>'300'),
|
||||
// array('name' => '销售实收账单', 'file_name' => 'bill/import/normal.html', 'app' => 'finance','order'=>'400'),
|
||||
// array('name' => '销售应收账单', 'file_name' => 'bill/import/ar.html', 'app' => 'finance','order'=>'500'),
|
||||
array('name' => '微信小店账单导入', 'file_name' => 'admin/bill/import/wxpay.html', 'type' => 'wxpay','order'=>'1300'),
|
||||
array('name' => '京东钱包导入', 'file_name' => 'admin/bill/import/jdwallet.html', 'type' => 'jdwallet','order'=>'1400'),
|
||||
);
|
||||
// 定位到具体的TAB
|
||||
if (isset($_GET['tab']) && isset($settingTabs[intval($_GET['tab'])])) $settingTabs[intval($_GET['tab'])]['current'] = true;
|
||||
$this->pagedata['settingTabs'] = $settingTabs;
|
||||
|
||||
/*$get = kernel::single('base_component_request')->get_get();
|
||||
|
||||
$this->pagedata['ctler'] = 'financebase_mdl_bill';
|
||||
$this->pagedata['add'] = 'financebase';
|
||||
|
||||
unset($get['app'],$get['ctl'],$get['act'],$get['add'],$get['ctler']);
|
||||
$this->pagedata['data'] = $get;
|
||||
|
||||
$ioType = array();
|
||||
foreach( kernel::servicelist('omecsv_io') as $aIo ){
|
||||
$ioType[$aIo->io_type_name] = '.'.$aIo->io_type_name;
|
||||
}
|
||||
|
||||
$platformConfig = $this->getPlatformConfig();
|
||||
|
||||
$this->pagedata['ioType'] = $ioType;*/
|
||||
$this->pagedata['init_time'] = app::get('finance')->getConf('finance_setting_init_time');
|
||||
$this->pagedata['shop_list_alipay'] = financebase_func::getShopList(array('taobao','tmall'));
|
||||
$this->pagedata['shop_list_360buy'] = financebase_func::getShopList('360buy');
|
||||
$this->pagedata['shop_list_luban'] = financebase_func::getShopList('luban');
|
||||
$this->pagedata['shop_list_youzan'] = financebase_func::getShopList('youzan');
|
||||
$this->pagedata['shop_list_pinduoduo'] = financebase_func::getShopList('pinduoduo');
|
||||
$this->pagedata['shop_list_wechatpay'] = financebase_func::getShopList(['wx','weixinshop','website','youzan']);
|
||||
$this->pagedata['shop_list_wxpay'] = financebase_func::getShopList(['wx','youzan','wxshipin']);
|
||||
// 生成卡片配置
|
||||
$settingTabs = array();
|
||||
foreach($platformConfig as $type => $config) {
|
||||
$settingTabs[] = array(
|
||||
'name' => $config['name'],
|
||||
'type' => $type,
|
||||
'icon' => $config['icon'],
|
||||
'order' => $config['order'],
|
||||
'template_file' => $config['template_file'],
|
||||
'template_fields' => isset($config['template_fields']) ? $config['template_fields'] : '',
|
||||
'file_format' => isset($config['file_format']) ? $config['file_format'] : '.csv、 .xls、 .xlsx'
|
||||
);
|
||||
}
|
||||
|
||||
// 按order排序
|
||||
usort($settingTabs, function($a, $b) {
|
||||
return intval($a['order']) - intval($b['order']);
|
||||
});
|
||||
|
||||
$this->pagedata['settingTabs'] = $settingTabs;
|
||||
|
||||
// 检查账期设置
|
||||
// app::get('finance')->setConf('finance_setting_init_time',[]);
|
||||
$init_time = app::get('finance')->getConf('finance_setting_init_time');
|
||||
$this->pagedata['init_time'] = $init_time;
|
||||
|
||||
// 将平台配置传递给前端,统一配置管理
|
||||
$this->pagedata['platformConfig'] = $platformConfig;
|
||||
|
||||
// 直接输出JavaScript配置,避免Smarty模板问题
|
||||
$this->pagedata['platformConfigJs'] = json_encode($platformConfig);
|
||||
|
||||
// 获取 finder_id 并传递给模板(用于权限验证)
|
||||
// 使用与 desktop_controller::page() 相同的逻辑生成 finder_id
|
||||
$_GET['finder_id'] || $_GET['finder_id'] = ($_GET['_finder']['finder_id'] ? : ($_GET['find_id'] ? : substr(md5($_SERVER['QUERY_STRING']),5,6)));
|
||||
$this->pagedata['finder_id'] = $_GET['finder_id'];
|
||||
|
||||
// 卡片布局不再需要预先加载店铺列表,改为按需通过AJAX加载
|
||||
$this->page('admin/bill/import.html');
|
||||
}
|
||||
|
||||
@@ -303,8 +437,8 @@ class financebase_ctl_admin_shop_settlement_bill extends desktop_controller
|
||||
exit;
|
||||
}
|
||||
|
||||
//data
|
||||
$dataList = app::get('financebase')->model('base')->getList('id,unique_id,shop_id,trade_no', $filter, $offset, $limit, 'id asc');
|
||||
//data - 获取数据时包含 platform_type 字段
|
||||
$dataList = app::get('financebase')->model('base')->getList('id,unique_id,shop_id,trade_no,platform_type', $filter, $offset, $limit, 'id asc');
|
||||
|
||||
//check
|
||||
if(empty($dataList)){
|
||||
@@ -315,18 +449,25 @@ class financebase_ctl_admin_shop_settlement_bill extends desktop_controller
|
||||
//count
|
||||
$retArr['itotal'] = count($dataList);
|
||||
|
||||
$oFunc = kernel::single('financebase_func');
|
||||
$node_type_ref = $oFunc->getConfig('node_type');
|
||||
$shopInfo = app::get('ome')->model('shop')->getList('shop_id,shop_type',array('shop_id'=>array_unique(array_column($dataList, 'shop_id'))));
|
||||
$shopInfo = array_column($shopInfo, null, 'shop_id');
|
||||
//list
|
||||
//list - 直接使用 platform_type 来定位 worker 类
|
||||
foreach ($dataList as $key => $value) {
|
||||
if(empty($node_type_ref[$shopInfo[$value['shop_id']]['shop_type']])) {
|
||||
// 检查 platform_type 是否存在
|
||||
if(empty($value['platform_type'])) {
|
||||
$retArr['ifail'] ++;
|
||||
$retArr['err_msg'][] = $value['trade_no'].':缺少店铺类型';
|
||||
$retArr['err_msg'][] = $value['trade_no'].':缺少平台类型';
|
||||
continue;
|
||||
}
|
||||
$worker = "financebase_data_bill_".$node_type_ref[$shopInfo[$value['shop_id']]['shop_type']];
|
||||
|
||||
// 使用 platform_type 直接拼接 worker 类名
|
||||
$worker = "financebase_data_bill_".$value['platform_type'];
|
||||
|
||||
// 检查类是否存在
|
||||
if (!ome_func::class_exists($worker)) {
|
||||
$retArr['ifail'] ++;
|
||||
$retArr['err_msg'][] = $value['trade_no'].':平台类型['.$value['platform_type'].']无此类型的方法';
|
||||
continue;
|
||||
}
|
||||
|
||||
$params = [];
|
||||
$params['shop_id'] = $value['shop_id'];
|
||||
$params['ids'] = [$value['unique_id']];
|
||||
@@ -487,6 +628,39 @@ class financebase_ctl_admin_shop_settlement_bill extends desktop_controller
|
||||
|
||||
}
|
||||
|
||||
// 获取店铺列表(用于弹层)
|
||||
public function getShopList(){
|
||||
$type = $_GET['type'];
|
||||
|
||||
if(!$type) {
|
||||
echo 'Error: 缺少类型参数';
|
||||
return;
|
||||
}
|
||||
|
||||
$platformConfig = $this->getPlatformConfig();
|
||||
|
||||
if(!isset($platformConfig[$type])) {
|
||||
echo 'Error: 不支持的类型';
|
||||
return;
|
||||
}
|
||||
|
||||
$config = $platformConfig[$type];
|
||||
|
||||
// 根据配置获取店铺列表
|
||||
if($config['shop_filter'] === 'all') {
|
||||
$shopList = financebase_func::getShopList(financebase_func::getShopType());
|
||||
} else {
|
||||
$shop_type = isset($config['shop_filter']['shop_type']) ? $config['shop_filter']['shop_type'] : '';
|
||||
// 将整个 shop_filter 作为第三个参数传递,支持更灵活的筛选条件
|
||||
$shopList = financebase_func::getShopList($shop_type, '', $config['shop_filter']);
|
||||
}
|
||||
|
||||
// 直接输出店铺选项HTML
|
||||
foreach($shopList as $shop) {
|
||||
echo '<option value="' . $shop['shop_id'] . '">' . $shop['name'] . '</option>';
|
||||
}
|
||||
}
|
||||
|
||||
// 导入未匹配订单号
|
||||
/**
|
||||
* importUnMatch
|
||||
|
||||
416
app/financebase/controller/admin/shop/settlement/gap.php
Normal file
416
app/financebase/controller/admin/shop/settlement/gap.php
Normal file
@@ -0,0 +1,416 @@
|
||||
<?php
|
||||
/**
|
||||
* 差异类型控制层
|
||||
*
|
||||
* @author 334395174@qq.com
|
||||
* @version 0.1
|
||||
*/
|
||||
|
||||
class financebase_ctl_admin_shop_settlement_gap extends desktop_controller
|
||||
{
|
||||
|
||||
/**
|
||||
* 差异类型列表分栏菜单
|
||||
*
|
||||
* @param Null
|
||||
* @return Array
|
||||
*/
|
||||
public function _views()
|
||||
{
|
||||
#不是列表时隐藏Tab
|
||||
if ($_GET['act'] != 'index') {
|
||||
return array();
|
||||
}
|
||||
|
||||
$gapObj = app::get('financebase')->model('gap');
|
||||
|
||||
$sub_menu = array(
|
||||
0 => array('label' => app::get('base')->_('有效'), 'filter' => array('status' => '1'), 'optional' => false),
|
||||
1 => array('label' => app::get('base')->_('无效'), 'filter' => array('status' => '0'), 'optional' => false),
|
||||
);
|
||||
|
||||
foreach ($sub_menu as $k => $v) {
|
||||
$sub_menu[$k]['filter'] = $v['filter'] ? $v['filter'] : null;
|
||||
$sub_menu[$k]['addon'] = $gapObj->count($v['filter']);
|
||||
$sub_menu[$k]['href'] = 'index.php?app=financebase&ctl=admin_shop_settlement_gap&act=index&view=' . $k;
|
||||
}
|
||||
|
||||
return $sub_menu;
|
||||
}
|
||||
|
||||
// 差异类型列表
|
||||
public function index()
|
||||
{
|
||||
// 根据view设置base_filter
|
||||
$base_filter = array();
|
||||
$view = isset($_GET['view']) ? intval($_GET['view']) : 0;
|
||||
|
||||
if ($view == 0) {
|
||||
// 有效
|
||||
$base_filter = array('status' => '1');
|
||||
} elseif ($view == 1) {
|
||||
// 无效
|
||||
$base_filter = array('status' => '0');
|
||||
}
|
||||
|
||||
$actions = array();
|
||||
|
||||
// 新增按钮权限控制
|
||||
if (kernel::single('desktop_user')->has_permission('shop_settlement_gap_add')) {
|
||||
$actions[] = array(
|
||||
'label'=>'新增',
|
||||
'href'=>'index.php?app=financebase&ctl=admin_shop_settlement_gap&act=setGap&p[0]=0&singlepage=false&finder_id='.$_GET['finder_id'],
|
||||
'target'=>'dialog::{width:600,height:400,resizeable:false,title:\'新增差异类型\'}'
|
||||
);
|
||||
}
|
||||
|
||||
// 置为无效按钮权限控制 - 只在有效tab中显示
|
||||
if (kernel::single('desktop_user')->has_permission('shop_settlement_gap_delete') && $view == 0) {
|
||||
$actions[] = array(
|
||||
'label' => '置为无效',
|
||||
'confirm' => '你确定要将选中的差异类型置为无效吗?',
|
||||
'submit' => 'index.php?app=financebase&ctl=admin_shop_settlement_gap&act=disableGap',
|
||||
'target' => 'refresh'
|
||||
);
|
||||
}
|
||||
|
||||
// 恢复按钮权限控制 - 只在无效tab中显示
|
||||
if (kernel::single('desktop_user')->has_permission('shop_settlement_gap_restore') && $view == 1) {
|
||||
$actions[] = array(
|
||||
'label' => '置为有效',
|
||||
'confirm' => '你确定要将选中的差异类型置为有效吗?',
|
||||
'submit' => 'index.php?app=financebase&ctl=admin_shop_settlement_gap&act=restoreGap',
|
||||
'target' => 'refresh'
|
||||
);
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'title'=>'差异类型设置',
|
||||
'actions' => $actions,
|
||||
'base_filter' => $base_filter,
|
||||
'use_buildin_set_tag'=>false,
|
||||
'use_buildin_recycle'=>false,
|
||||
'use_buildin_filter'=>false,
|
||||
'use_buildin_export'=> false,
|
||||
'use_buildin_import'=> false,
|
||||
'orderBy'=>'id',
|
||||
);
|
||||
|
||||
$this->finder('financebase_mdl_gap',$params);
|
||||
}
|
||||
|
||||
// 设置差异类型
|
||||
public function setGap($id=0)
|
||||
{
|
||||
// 检查权限
|
||||
if ($id > 0) {
|
||||
// 编辑模式
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_gap_edit')) {
|
||||
$this->splash('error', null, '您没有编辑差异类型的权限');
|
||||
}
|
||||
} else {
|
||||
// 新增模式
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_gap_add')) {
|
||||
$this->splash('error', null, '您没有新增差异类型的权限');
|
||||
}
|
||||
}
|
||||
|
||||
$gap_info = array('id'=>$id);
|
||||
$oGap = app::get('financebase')->model("gap");
|
||||
if($id)
|
||||
{
|
||||
$gap_info=$oGap->db_dump(array('id'=>$id));
|
||||
}
|
||||
|
||||
// 获取会计科目列表 - 只获取有效且排除内置特殊场景科目
|
||||
$oAccount = app::get('financebase')->model("account_chart");
|
||||
$account_list = $oAccount->getList('id,account,description,postingkey', array('disabled' => 'false', 'account_category' => ''));
|
||||
$this->pagedata['account_list'] = $account_list;
|
||||
$this->pagedata['gap_info'] = $gap_info;
|
||||
$this->display("admin/gap/gap.html");
|
||||
}
|
||||
|
||||
// 保存差异类型
|
||||
public function saveGap()
|
||||
{
|
||||
$this->begin('index.php?app=financebase&ctl=admin_shop_settlement_gap&act=index');
|
||||
|
||||
// 检查权限
|
||||
$is_edit = !empty($_POST['id']);
|
||||
if ($is_edit) {
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_gap_edit')) {
|
||||
$this->end(false, '您没有编辑差异类型的权限');
|
||||
}
|
||||
} else {
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_gap_add')) {
|
||||
$this->end(false, '您没有新增差异类型的权限');
|
||||
}
|
||||
}
|
||||
|
||||
$oGap = app::get('financebase')->model("gap");
|
||||
$data = array();
|
||||
|
||||
$data['id'] = intval($_POST['id']);
|
||||
|
||||
$data['gap_name'] = htmlspecialchars($_POST['gap_name']);
|
||||
$data['account_id_plus'] = intval($_POST['account_id_plus']);
|
||||
$data['account_id_minus'] = intval($_POST['account_id_minus']);
|
||||
|
||||
// 判断差异类型是否唯一
|
||||
if($oGap->isExist(array('gap_name'=>$data['gap_name']),$data['id']))
|
||||
{
|
||||
$this->end(false, "差异类型有重名");
|
||||
}
|
||||
|
||||
// 获取原始数据用于日志记录(仅编辑时需要)
|
||||
$existing = null;
|
||||
if ($is_edit) {
|
||||
$existing = $oGap->dump(array('id' => $data['id']));
|
||||
}
|
||||
|
||||
if($oGap->save($data))
|
||||
{
|
||||
// 记录操作日志和快照
|
||||
$action = $is_edit ? 'edit' : 'add';
|
||||
$this->_recordLog($action, $data['id'], $data, $existing);
|
||||
$this->end(true, app::get('base')->_('保存成功'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->end(false, app::get('base')->_('保存失败'));
|
||||
}
|
||||
}
|
||||
|
||||
// 置为无效差异类型
|
||||
public function disableGap()
|
||||
{
|
||||
$this->begin('index.php?app=financebase&ctl=admin_shop_settlement_gap&act=index');
|
||||
|
||||
// 检查置为无效权限
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_gap_delete')) {
|
||||
$this->end(false, '您没有置为无效差异类型的权限');
|
||||
}
|
||||
|
||||
if($_POST['isSelectedAll'] == '_ALL_'){
|
||||
$this->end(false,'不支持全选置为无效');
|
||||
}
|
||||
|
||||
if(empty($_POST['id'])){
|
||||
$this->end(false,'请选择要置为无效的差异类型');
|
||||
}
|
||||
|
||||
$oGap = app::get('financebase')->model("gap");
|
||||
|
||||
foreach($_POST['id'] as $gap_id){
|
||||
if($gap_id){
|
||||
// 获取差异类型信息
|
||||
$gap_info = $oGap->dump(array('id'=>$gap_id), 'gap_name');
|
||||
if(!$gap_info){
|
||||
$this->end(false, '差异类型不存在');
|
||||
}
|
||||
|
||||
$gap_name = $gap_info['gap_name'];
|
||||
|
||||
// 执行软删除 - 将status设置为0
|
||||
if(!$oGap->update(array('status' => '0'), array('id'=>$gap_id))){
|
||||
$this->end(false, "置为无效差异类型【{$gap_name}】失败");
|
||||
}
|
||||
|
||||
// 记录操作日志
|
||||
$this->_recordLog('delete', $gap_id);
|
||||
}
|
||||
}
|
||||
|
||||
$this->end(true, '置为无效成功');
|
||||
}
|
||||
|
||||
// 恢复差异类型
|
||||
public function restoreGap()
|
||||
{
|
||||
$this->begin('index.php?app=financebase&ctl=admin_shop_settlement_gap&act=index');
|
||||
|
||||
// 检查恢复权限
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_gap_restore')) {
|
||||
$this->end(false, '您没有恢复差异类型的权限');
|
||||
}
|
||||
|
||||
if($_POST['isSelectedAll'] == '_ALL_'){
|
||||
$this->end(false,'不支持全选恢复');
|
||||
}
|
||||
|
||||
if(empty($_POST['id'])){
|
||||
$this->end(false,'请选择要恢复的差异类型');
|
||||
}
|
||||
|
||||
$oGap = app::get('financebase')->model("gap");
|
||||
|
||||
foreach($_POST['id'] as $gap_id){
|
||||
if($gap_id){
|
||||
// 获取差异类型信息
|
||||
$gap_info = $oGap->dump(array('id'=>$gap_id), 'gap_name');
|
||||
if(!$gap_info){
|
||||
$this->end(false, '差异类型不存在');
|
||||
}
|
||||
|
||||
$gap_name = $gap_info['gap_name'];
|
||||
|
||||
// 执行恢复 - 将status设置为1
|
||||
if(!$oGap->update(array('status' => '1'), array('id'=>$gap_id))){
|
||||
$this->end(false, "恢复差异类型【{$gap_name}】失败");
|
||||
}
|
||||
|
||||
// 记录操作日志
|
||||
$this->_recordLog('restore', $gap_id);
|
||||
}
|
||||
}
|
||||
|
||||
$this->end(true, '置为有效成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录操作日志
|
||||
*
|
||||
* @param string $action 操作类型:add/edit/delete/restore
|
||||
* @param int $gap_id 差异类型ID
|
||||
* @param array $data 新数据(编辑时需要)
|
||||
* @param array $existing 原始数据(编辑时需要)
|
||||
*/
|
||||
private function _recordLog($action, $gap_id, $data = null, $existing = null)
|
||||
{
|
||||
$omeLogMdl = app::get('ome')->model('operation_log');
|
||||
|
||||
// 根据操作类型设置日志参数
|
||||
switch ($action) {
|
||||
case 'add':
|
||||
$log_key = 'gap_add@financebase';
|
||||
$memo = '新增差异类型';
|
||||
break;
|
||||
case 'edit':
|
||||
$log_key = 'gap_edit@financebase';
|
||||
$memo = '编辑差异类型';
|
||||
break;
|
||||
case 'delete':
|
||||
$log_key = 'gap_delete@financebase';
|
||||
$memo = '置为无效差异类型';
|
||||
break;
|
||||
case 'restore':
|
||||
$log_key = 'gap_restore@financebase';
|
||||
$memo = '恢复差异类型';
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// 记录操作日志
|
||||
$log_id = $omeLogMdl->write_log($log_key, $gap_id, $memo);
|
||||
|
||||
// 生成操作快照(只有编辑时才存储)
|
||||
if ($log_id && $action == 'edit' && $existing && $data) {
|
||||
$shootMdl = app::get('ome')->model('operation_log_snapshoot');
|
||||
|
||||
// 处理快照数据中的会计科目显示格式
|
||||
$snapshoot_data = $this->_formatAccountDisplay($existing);
|
||||
$updated_data = $this->_formatAccountDisplay($data);
|
||||
|
||||
$snapshoot = json_encode($snapshoot_data, JSON_UNESCAPED_UNICODE);
|
||||
$updated = json_encode($updated_data, JSON_UNESCAPED_UNICODE);
|
||||
$tmp = [
|
||||
'log_id' => $log_id,
|
||||
'snapshoot' => $snapshoot,
|
||||
'updated' => $updated
|
||||
];
|
||||
$shootMdl->insert($tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化会计科目显示格式
|
||||
*
|
||||
* @param array $data 数据数组
|
||||
* @return array 格式化后的数据数组
|
||||
*/
|
||||
private function _formatAccountDisplay($data)
|
||||
{
|
||||
if (empty($data['account_id_plus']) && empty($data['account_id_minus'])) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
// 获取会计科目列表
|
||||
$oAccount = app::get('financebase')->model("account_chart");
|
||||
$account_list = $oAccount->getList('id,account,description,postingkey', array('disabled' => 'false'));
|
||||
|
||||
// 使用array_column创建会计科目映射
|
||||
$account_map = array();
|
||||
foreach ($account_list as $account) {
|
||||
$account_map[$account['id']] = '[' . $account['account'] . '-' . $account['postingkey'] . ']' . $account['description'];
|
||||
}
|
||||
|
||||
// 格式化会计科目显示
|
||||
if (!empty($data['account_id_plus']) && isset($account_map[$data['account_id_plus']])) {
|
||||
$data['account_id_plus'] = $account_map[$data['account_id_plus']];
|
||||
}
|
||||
|
||||
if (!empty($data['account_id_minus']) && isset($account_map[$data['account_id_minus']])) {
|
||||
$data['account_id_minus'] = $account_map[$data['account_id_minus']];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看快照
|
||||
*/
|
||||
public function show_history($log_id)
|
||||
{
|
||||
$logSnapshootMdl = app::get('ome')->model('operation_log_snapshoot');
|
||||
$log = $logSnapshootMdl->db_dump(['log_id' => $log_id]);
|
||||
$row = json_decode($log['snapshoot'], 1);
|
||||
|
||||
if (!$row) {
|
||||
$this->splash('error', null, '快照数据不存在');
|
||||
}
|
||||
|
||||
// 对比数据差异
|
||||
$diff_data = array();
|
||||
if (!empty($log['updated'])) {
|
||||
$updated_data = json_decode($log['updated'], 1);
|
||||
$diff_data = $this->_compareGapData($row, $updated_data);
|
||||
}
|
||||
|
||||
// 获取会计科目列表 - 只获取有效的科目
|
||||
$oAccount = app::get('financebase')->model("account_chart");
|
||||
$account_list = $oAccount->getList('id,account,description,postingkey', array('disabled' => 'false'));
|
||||
|
||||
$this->pagedata['gap_info'] = $row;
|
||||
$this->pagedata['diff_data'] = $diff_data;
|
||||
$this->pagedata['account_list'] = $account_list;
|
||||
$this->pagedata['history'] = true;
|
||||
$this->singlepage("admin/gap/gap.html");
|
||||
}
|
||||
|
||||
/**
|
||||
* 对比差异类型数据差异
|
||||
*/
|
||||
private function _compareGapData($old_data, $new_data)
|
||||
{
|
||||
$diff_data = array();
|
||||
|
||||
// 需要对比的字段
|
||||
$compare_fields = array('gap_name', 'account_id_plus', 'account_id_minus');
|
||||
|
||||
foreach ($compare_fields as $field) {
|
||||
$old_value = isset($old_data[$field]) ? $old_data[$field] : '';
|
||||
$new_value = isset($new_data[$field]) ? $new_data[$field] : '';
|
||||
|
||||
// 只有有变化时才添加到diff_data
|
||||
if ($old_value != $new_value) {
|
||||
$diff_data[$field] = array(
|
||||
'old_value' => $old_value,
|
||||
'new_value' => $new_value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $diff_data;
|
||||
}
|
||||
}
|
||||
@@ -20,27 +20,87 @@
|
||||
* @author 334395174@qq.com
|
||||
* @version 0.1
|
||||
*/
|
||||
|
||||
class financebase_ctl_admin_shop_settlement_rules extends desktop_controller
|
||||
{
|
||||
|
||||
// 违禁词列表
|
||||
/**
|
||||
* index
|
||||
* @return mixed 返回值
|
||||
* 收支分类列表分栏菜单
|
||||
*
|
||||
* @param Null
|
||||
* @return Array
|
||||
*/
|
||||
public function _views()
|
||||
{
|
||||
#不是列表时隐藏Tab
|
||||
if ($_GET['act'] != 'index') {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function index()
|
||||
$rulesObj = app::get('financebase')->model('bill_category_rules');
|
||||
|
||||
$sub_menu = array(
|
||||
0 => array('label' => app::get('base')->_('有效'), 'filter' => array('disabled' => 'false'), 'optional' => false),
|
||||
1 => array('label' => app::get('base')->_('无效'), 'filter' => array('disabled' => 'true'), 'optional' => false),
|
||||
);
|
||||
|
||||
foreach ($sub_menu as $k => $v) {
|
||||
$sub_menu[$k]['filter'] = $v['filter'] ? $v['filter'] : null;
|
||||
$sub_menu[$k]['addon'] = $rulesObj->count($v['filter']);
|
||||
$sub_menu[$k]['href'] = 'index.php?app=financebase&ctl=admin_shop_settlement_rules&act=index&view=' . $k;
|
||||
}
|
||||
|
||||
return $sub_menu;
|
||||
}
|
||||
|
||||
// 收支分类列表
|
||||
public function index()
|
||||
{
|
||||
|
||||
$use_buildin_export = false;
|
||||
$use_buildin_import = false;
|
||||
|
||||
|
||||
|
||||
// 根据view设置base_filter
|
||||
$base_filter = array();
|
||||
$actions = array(
|
||||
array('label'=>'新增','href'=>'index.php?app=financebase&ctl=admin_shop_settlement_rules&act=setCategory&p[0]=0&singlepage=false&finder_id='.$_GET['finder_id'],'target'=>'dialog::{width:550,height:400,resizeable:false,title:\'新增收支分类\'}'),
|
||||
);
|
||||
$view = isset($_GET['view']) ? intval($_GET['view']) : 0;
|
||||
|
||||
if ($view == 0) {
|
||||
// 有效
|
||||
$base_filter = array('disabled' => 'false');
|
||||
} elseif ($view == 1) {
|
||||
// 无效
|
||||
$base_filter = array('disabled' => 'true');
|
||||
}
|
||||
|
||||
$actions = array();
|
||||
|
||||
// 新增按钮权限控制
|
||||
if (kernel::single('desktop_user')->has_permission('shop_settlement_rules_add')) {
|
||||
$actions[] = array(
|
||||
'label'=>'新增',
|
||||
'href'=>'index.php?app=financebase&ctl=admin_shop_settlement_rules&act=setCategory&p[0]=0&singlepage=false&finder_id='.$_GET['finder_id'],
|
||||
'target'=>'dialog::{width:550,height:400,resizeable:false,title:\'新增收支分类\'}'
|
||||
);
|
||||
}
|
||||
|
||||
// 置为无效按钮权限控制 - 只在有效tab中显示
|
||||
if (kernel::single('desktop_user')->has_permission('shop_settlement_rules_delete') && $view == 0) {
|
||||
$actions[] = array(
|
||||
'label' => '置为无效',
|
||||
'confirm' => '你确定要将选中的收支分类置为无效吗?',
|
||||
'submit' => 'index.php?app=financebase&ctl=admin_shop_settlement_rules&act=disableRules',
|
||||
'target' => 'refresh'
|
||||
);
|
||||
}
|
||||
|
||||
// 恢复按钮权限控制 - 只在无效tab中显示
|
||||
if (kernel::single('desktop_user')->has_permission('shop_settlement_rules_restore') && $view == 1) {
|
||||
$actions[] = array(
|
||||
'label' => '置为有效',
|
||||
'confirm' => '你确定要将选中的收支分类置为有效吗?',
|
||||
'submit' => 'index.php?app=financebase&ctl=admin_shop_settlement_rules&act=restoreRules',
|
||||
'target' => 'refresh'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +109,7 @@ class financebase_ctl_admin_shop_settlement_rules extends desktop_controller
|
||||
'actions' => $actions,
|
||||
'base_filter' => $base_filter,
|
||||
'use_buildin_set_tag'=>false,
|
||||
'use_buildin_recycle'=>true,
|
||||
'use_buildin_recycle'=>false,
|
||||
'use_buildin_filter'=>false,
|
||||
'use_buildin_export'=> $use_buildin_export,
|
||||
'use_buildin_import'=> $use_buildin_import,
|
||||
@@ -61,35 +121,57 @@ class financebase_ctl_admin_shop_settlement_rules extends desktop_controller
|
||||
|
||||
|
||||
// 设置具体类别名称
|
||||
/**
|
||||
* 设置Category
|
||||
* @param mixed $rule_id ID
|
||||
* @return mixed 返回操作结果
|
||||
*/
|
||||
public function setCategory($rule_id=0)
|
||||
{
|
||||
// 检查权限
|
||||
if ($rule_id > 0) {
|
||||
// 编辑模式
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_rules_edit')) {
|
||||
$this->splash('error', null, '您没有编辑收支分类的权限');
|
||||
}
|
||||
} else {
|
||||
// 新增模式
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_rules_add')) {
|
||||
$this->splash('error', null, '您没有新增收支分类的权限');
|
||||
}
|
||||
}
|
||||
|
||||
$rule_info = array('rule_id'=>$rule_id);
|
||||
$oRules = app::get('financebase')->model("bill_category_rules");
|
||||
if($rule_id)
|
||||
{
|
||||
$rule_info=$oRules->getRow('rule_id,bill_category,ordernum',array('rule_id'=>$rule_id));
|
||||
$rule_info=$oRules->getRow('rule_id,bill_category,ordernum,account_id_plus,account_id_minus,need_ar_verify',array('rule_id'=>$rule_id));
|
||||
}else{
|
||||
$row = $oRules->getRow('max(ordernum) as max',array());
|
||||
$rule_info['ordernum'] = $row ? $row['max'] + 1 : 1;
|
||||
$rule_info['need_ar_verify'] = 1; // 默认需要核对
|
||||
}
|
||||
|
||||
// 获取会计科目列表 - 只获取有效且排除内置特殊场景科目
|
||||
$oAccount = app::get('financebase')->model("account_chart");
|
||||
$account_list = $oAccount->getList('id,account,description,postingkey', array('disabled' => 'false', 'account_category' => ''));
|
||||
$this->pagedata['account_list'] = $account_list;
|
||||
$this->pagedata['rule_info'] = $rule_info;
|
||||
$this->display("admin/bill/category.html");
|
||||
}
|
||||
|
||||
// 保存具体类别名称
|
||||
/**
|
||||
* 保存Category
|
||||
* @return mixed 返回操作结果
|
||||
*/
|
||||
public function saveCategory()
|
||||
{
|
||||
$this->begin('index.php?app=financebase&ctl=admin_shop_settlement_rules&act=index');
|
||||
|
||||
// 检查权限
|
||||
$is_edit = !empty($_POST['rule_id']);
|
||||
if ($is_edit) {
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_rules_edit')) {
|
||||
$this->end(false, '您没有编辑收支分类的权限');
|
||||
}
|
||||
} else {
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_rules_add')) {
|
||||
$this->end(false, '您没有新增收支分类的权限');
|
||||
}
|
||||
}
|
||||
|
||||
$oRules = app::get('financebase')->model("bill_category_rules");
|
||||
$data = array();
|
||||
|
||||
@@ -101,6 +183,9 @@ class financebase_ctl_admin_shop_settlement_rules extends desktop_controller
|
||||
|
||||
$data['ordernum'] = intval($_POST['ordernum']);
|
||||
$data['bill_category'] = htmlspecialchars($_POST['bill_category']);
|
||||
$data['account_id_plus'] = intval($_POST['account_id_plus']);
|
||||
$data['account_id_minus'] = intval($_POST['account_id_minus']);
|
||||
$data['need_ar_verify'] = intval($_POST['need_ar_verify']);
|
||||
|
||||
// 判断具体类别是否唯一
|
||||
if($oRules->isExist(array('bill_category'=>$data['bill_category']),$data['rule_id']))
|
||||
@@ -114,8 +199,17 @@ class financebase_ctl_admin_shop_settlement_rules extends desktop_controller
|
||||
$this->end(false, app::get('base')->_('优先级已存在'));
|
||||
}
|
||||
|
||||
// 获取原始数据用于日志记录
|
||||
$existing = null;
|
||||
if ($data['rule_id']) {
|
||||
$existing = $oRules->dump(array('rule_id' => $data['rule_id']));
|
||||
}
|
||||
|
||||
if($oRules->save($data))
|
||||
{
|
||||
// 记录操作日志和快照
|
||||
$action = $data['rule_id'] ? 'edit' : 'add';
|
||||
$this->_recordLog($action, $data['rule_id'], $data, $existing);
|
||||
$this->end(true, app::get('base')->_('保存成功'));
|
||||
}
|
||||
else
|
||||
@@ -163,10 +257,6 @@ class financebase_ctl_admin_shop_settlement_rules extends desktop_controller
|
||||
}
|
||||
|
||||
// 保存规则
|
||||
/**
|
||||
* 保存Rule
|
||||
* @return mixed 返回操作结果
|
||||
*/
|
||||
public function saveRule()
|
||||
{
|
||||
|
||||
@@ -181,21 +271,27 @@ class financebase_ctl_admin_shop_settlement_rules extends desktop_controller
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
foreach ($_POST['rule_op'] as $k => $v) {
|
||||
foreach ($v as $k2 => $v2) {
|
||||
$rule_content[$i][$k2] = ['rule_type'=>$_POST['rule_type'][$k][$k2],'rule_value'=>$_POST['rule_value'][$k][$k2],'rule_op'=>$v2,'rule_filter'=>$_POST['rule_filter'][$k][$k2]];
|
||||
if(isset($_POST['rule_op']) && is_array($_POST['rule_op'])){
|
||||
foreach ($_POST['rule_op'] as $k => $v) {
|
||||
foreach ($v as $k2 => $v2) {
|
||||
$rule_content[$i][$k2] = ['rule_type'=>$_POST['rule_type'][$k][$k2],'rule_value'=>$_POST['rule_value'][$k][$k2],'rule_op'=>$v2,'rule_filter'=>$_POST['rule_filter'][$k][$k2]];
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
if(!$rule_content)
|
||||
{
|
||||
$this->end(false, app::get('base')->_('规则不能为空'));
|
||||
}
|
||||
// 允许保存空规则数据
|
||||
// if(!$rule_content)
|
||||
// {
|
||||
// $this->end(false, app::get('base')->_('规则不能为空'));
|
||||
// }
|
||||
|
||||
$rule_info=$oRules->getRow('rule_id,rule_content',array('rule_id'=>$_POST['rule_id']));
|
||||
|
||||
$rule_info['rule_content'] = json_decode($rule_info['rule_content'],1);
|
||||
if(!is_array($rule_info['rule_content'])){
|
||||
$rule_info['rule_content'] = array();
|
||||
}
|
||||
|
||||
$rule_info['rule_content'][$_POST['platform_type']] = $rule_content;
|
||||
|
||||
@@ -225,5 +321,250 @@ class financebase_ctl_admin_shop_settlement_rules extends desktop_controller
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录操作日志和快照
|
||||
*
|
||||
* @param string $action 操作类型:add/edit/delete/restore
|
||||
* @param int $rule_id 规则ID
|
||||
* @param array $data 新数据(编辑时使用)
|
||||
* @param array $existing 原始数据(编辑时使用)
|
||||
*/
|
||||
private function _recordLog($action, $rule_id, $data = null, $existing = null)
|
||||
{
|
||||
$omeLogMdl = app::get('ome')->model('operation_log');
|
||||
|
||||
// 根据操作类型设置日志参数
|
||||
switch ($action) {
|
||||
case 'add':
|
||||
$log_key = 'bill_category_rules_add@financebase';
|
||||
$memo = '新增收支分类';
|
||||
break;
|
||||
case 'edit':
|
||||
$log_key = 'bill_category_rules_edit@financebase';
|
||||
$memo = '编辑收支分类';
|
||||
break;
|
||||
case 'delete':
|
||||
$log_key = 'bill_category_rules_delete@financebase';
|
||||
$memo = '置为无效收支分类';
|
||||
break;
|
||||
case 'restore':
|
||||
$log_key = 'bill_category_rules_restore@financebase';
|
||||
$memo = '恢复收支分类';
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// 记录操作日志
|
||||
$log_id = $omeLogMdl->write_log($log_key, $rule_id, $memo);
|
||||
|
||||
// 生成操作快照(只有编辑时才存储)
|
||||
if ($log_id && $action == 'edit' && $existing && $data) {
|
||||
$shootMdl = app::get('ome')->model('operation_log_snapshoot');
|
||||
|
||||
// 处理快照数据中的会计科目显示格式
|
||||
$snapshoot_data = $this->_formatAccountDisplay($existing);
|
||||
$updated_data = $this->_formatAccountDisplay($data);
|
||||
|
||||
$snapshoot = json_encode($snapshoot_data, JSON_UNESCAPED_UNICODE);
|
||||
$updated = json_encode($updated_data, JSON_UNESCAPED_UNICODE);
|
||||
$tmp = [
|
||||
'log_id' => $log_id,
|
||||
'snapshoot' => $snapshoot,
|
||||
'updated' => $updated
|
||||
];
|
||||
$shootMdl->insert($tmp);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 格式化会计科目显示格式
|
||||
*
|
||||
* @param array $data 数据数组
|
||||
* @return array 格式化后的数据数组
|
||||
*/
|
||||
private function _formatAccountDisplay($data)
|
||||
{
|
||||
if (empty($data['account_id_plus']) && empty($data['account_id_minus'])) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
// 获取会计科目列表
|
||||
$oAccount = app::get('financebase')->model("account_chart");
|
||||
$account_list = $oAccount->getList('id,account,description,postingkey', array('disabled' => 'false'));
|
||||
|
||||
// 使用array_column创建会计科目映射
|
||||
$account_map = array();
|
||||
foreach ($account_list as $account) {
|
||||
$account_map[$account['id']] = '[' . $account['account'] . '-' . $account['postingkey'] . ']' . $account['description'];
|
||||
}
|
||||
|
||||
// 格式化会计科目显示
|
||||
if (!empty($data['account_id_plus']) && isset($account_map[$data['account_id_plus']])) {
|
||||
$data['account_id_plus'] = $account_map[$data['account_id_plus']];
|
||||
}
|
||||
|
||||
if (!empty($data['account_id_minus']) && isset($account_map[$data['account_id_minus']])) {
|
||||
$data['account_id_minus'] = $account_map[$data['account_id_minus']];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看快照
|
||||
*/
|
||||
public function show_history($log_id)
|
||||
{
|
||||
$logSnapshootMdl = app::get('ome')->model('operation_log_snapshoot');
|
||||
$log = $logSnapshootMdl->db_dump(['log_id' => $log_id]);
|
||||
$row = json_decode($log['snapshoot'], 1);
|
||||
|
||||
if (!$row) {
|
||||
$this->splash('error', null, '快照数据不存在');
|
||||
}
|
||||
|
||||
// 对比数据差异
|
||||
$diff_data = array();
|
||||
if (!empty($log['updated'])) {
|
||||
$updated_data = json_decode($log['updated'], 1);
|
||||
$diff_data = $this->_compareRuleData($row, $updated_data);
|
||||
}
|
||||
|
||||
// 获取会计科目列表 - 只获取有效的科目
|
||||
$oAccount = app::get('financebase')->model("account_chart");
|
||||
$account_list = $oAccount->getList('id,account,description,postingkey', array('disabled' => 'false'));
|
||||
|
||||
$this->pagedata['rule_info'] = $row;
|
||||
$this->pagedata['diff_data'] = $diff_data;
|
||||
$this->pagedata['account_list'] = $account_list;
|
||||
$this->pagedata['history'] = true;
|
||||
$this->singlepage("admin/bill/category.html");
|
||||
}
|
||||
|
||||
/**
|
||||
* 对比规则数据差异
|
||||
*/
|
||||
private function _compareRuleData($old_data, $new_data)
|
||||
{
|
||||
$diff_data = array();
|
||||
|
||||
// 需要对比的字段
|
||||
$compare_fields = array('bill_category', 'ordernum', 'account_id_plus', 'account_id_minus', 'need_ar_verify');
|
||||
|
||||
foreach ($compare_fields as $field) {
|
||||
$old_value = isset($old_data[$field]) ? $old_data[$field] : '';
|
||||
$new_value = isset($new_data[$field]) ? $new_data[$field] : '';
|
||||
|
||||
// 特殊处理AR核对状态字段
|
||||
if ($field == 'need_ar_verify') {
|
||||
$old_value = $old_value == 1 ? '需核对AR' : '无需核对AR';
|
||||
$new_value = $new_value == 1 ? '需核对AR' : '无需核对AR';
|
||||
}
|
||||
|
||||
// 特殊处理会计科目字段
|
||||
if (in_array($field, array('account_id_plus', 'account_id_minus'))) {
|
||||
$old_value = $old_value ?: '未设置';
|
||||
$new_value = $new_value ?: '未设置';
|
||||
}
|
||||
|
||||
// 只有有变化时才添加到diff_data
|
||||
if ($old_value != $new_value) {
|
||||
$diff_data[$field] = array(
|
||||
'old_value' => $old_value,
|
||||
'new_value' => $new_value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $diff_data;
|
||||
}
|
||||
|
||||
// 置为无效收支分类
|
||||
public function disableRules()
|
||||
{
|
||||
$this->begin('index.php?app=financebase&ctl=admin_shop_settlement_rules&act=index');
|
||||
|
||||
// 检查置为无效权限
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_rules_delete')) {
|
||||
$this->end(false, '您没有置为无效收支分类的权限');
|
||||
}
|
||||
|
||||
if($_POST['isSelectedAll'] == '_ALL_'){
|
||||
$this->end(false,'不支持全选置为无效');
|
||||
}
|
||||
|
||||
if(empty($_POST['rule_id'])){
|
||||
$this->end(false,'请选择要置为无效的收支分类');
|
||||
}
|
||||
|
||||
$oRules = app::get('financebase')->model("bill_category_rules");
|
||||
|
||||
foreach($_POST['rule_id'] as $rule_id){
|
||||
if($rule_id){
|
||||
// 获取收支分类信息
|
||||
$rule_info = $oRules->dump(array('rule_id'=>$rule_id), 'bill_category');
|
||||
if(!$rule_info){
|
||||
$this->end(false, '收支分类不存在');
|
||||
}
|
||||
|
||||
$rule_name = $rule_info['bill_category'];
|
||||
|
||||
// 执行软删除 - 将disabled设置为true
|
||||
if(!$oRules->update(array('disabled' => 'true'), array('rule_id'=>$rule_id))){
|
||||
$this->end(false, "置为无效收支分类【{$rule_name}】失败");
|
||||
}
|
||||
|
||||
// 记录操作日志
|
||||
$this->_recordLog('delete', $rule_id);
|
||||
}
|
||||
}
|
||||
|
||||
$this->end(true, '置为无效成功');
|
||||
}
|
||||
|
||||
// 恢复收支分类
|
||||
public function restoreRules()
|
||||
{
|
||||
$this->begin('index.php?app=financebase&ctl=admin_shop_settlement_rules&act=index');
|
||||
|
||||
// 检查恢复权限
|
||||
if (!kernel::single('desktop_user')->has_permission('shop_settlement_rules_restore')) {
|
||||
$this->end(false, '您没有恢复收支分类的权限');
|
||||
}
|
||||
|
||||
if($_POST['isSelectedAll'] == '_ALL_'){
|
||||
$this->end(false,'不支持全选恢复');
|
||||
}
|
||||
|
||||
if(empty($_POST['rule_id'])){
|
||||
$this->end(false,'请选择要恢复的收支分类');
|
||||
}
|
||||
|
||||
$oRules = app::get('financebase')->model("bill_category_rules");
|
||||
|
||||
foreach($_POST['rule_id'] as $rule_id){
|
||||
if($rule_id){
|
||||
// 获取收支分类信息
|
||||
$rule_info = $oRules->dump(array('rule_id'=>$rule_id), 'bill_category');
|
||||
if(!$rule_info){
|
||||
$this->end(false, '收支分类不存在');
|
||||
}
|
||||
|
||||
$rule_name = $rule_info['bill_category'];
|
||||
|
||||
// 执行恢复 - 将disabled设置为false
|
||||
if(!$oRules->update(array('disabled' => 'false'), array('rule_id'=>$rule_id))){
|
||||
$this->end(false, "恢复收支分类【{$rule_name}】失败");
|
||||
}
|
||||
|
||||
// 记录操作日志
|
||||
$this->_recordLog('restore', $rule_id);
|
||||
}
|
||||
}
|
||||
|
||||
$this->end(true, '置为有效成功');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user