Files
ctms-yii/ctms-api/controllers/gm/v1/FeeorderController.php
T
fm453 270b881437 ADD:添加后台管理端接口;
DEL:删除不必要的头部注释;
FIX:修正若干已知错误;
2025-07-13 19:40:10 +08:00

994 lines
32 KiB
PHP
Executable File

<?php
namespace api\controllers\gm\v1;
use Yii;
use yii\data\Pagination;
use addons\models\AcFeeOrder;
use addons\models\AcOrder;
use addons\models\AcStore;
use addons\models\AcEmployee;
class FeeorderController extends Common
{
public function beforeAction($action)
{
if (!$this->pid) {
$this->result('您正使用本系统内部接口,禁止非法链接使用!');
}
return parent::beforeAction($action);
}
public function actionIndex()
{
$apis = [
'list' => '列表',
'detail' => '详情',
'add' => '新增',
'edit' => '编辑',
'delete' => '删除',
'apply-status' => '获取票据单支付状态字典',
'apply-chonghong'=>'申请冲红',
'stop-chonghong'=>'终止冲红申请',
'save-chonghong'=>'冲红票据保存',
'caiwu'=>'财务审核',
];
$this->result('您正使用CMTS-GM系统运单费用管理接口!', $apis, 200);
}
/*费用列表*/
public function actionList()
{
$s = $this->search();
$res = $s['res'];
if (!$res) {
$this->result('没有查询到相应的数据!', [], 0);
}
$data= [
'total'=>$s['query']->count(),
'fees' => $res,
'page'=>$this->page
];
$this->result('费用记录查询成功!', $data, 200);
}
public function actionDetail()
{
$pid = $this->pid;
$post = $this->postdata;
$id = isset($post['id']) ? $post['id'] : 0;
if ($id <= 0) {
$this->result('查询参数错误!');
}
$model = new AcFeeOrder();
$detail = $model->findOne($id)->toArray();
if(!$detail) $this->result('未查询到相应数据');
$res = $this->showFee($detail);
$this->result('查询成功!', $res, 200);
}
public function actionAdd()
{
//数据预检查、编排
$pre = $this->preSave('add');
if(!$pre['data']) $this->result('数据预检查未通过,保存失败', $pre['data'], 100);
//保存资料
$model = new AcFeeOrder();
foreach ($pre['data'] as $key => $val) {
$model->$key = $val;
}
$res = $model->save();
$msg = '数据保存失败!';
if(!$res) $this->result($msg, [], 100);
$msg = '数据保存成功!';
if($pre['err']) $msg .= $pre['err_msg'];
$return = [];
$return['id']= $model->attributes['id']; //获取插入后id;
$this->result($msg,$return, 200);
}
public function actionEdit()
{
$detail = $this->preUpdate();
if (in_array($detail->status_code, [1, -2, 99])) {
//不允许修改已被财务确认的表单
$this->result('订单已入财务数据,不可修改!', [], 403);
}
$res = $this->userPrivilege($this->user_info,'feeOrderEdit',$detail);
if(!$res) $this->result('您没有操作权限!',[],403);
//数据预检查、编排
$data = $this->preSave('edit',$detail);
if(!$data) $this->result('数据预检查未通过,保存失败', $data, 100);
//保存资料
foreach ($data as $key=>$val) {
$detail->$key = $val;
}
$res = $detail->save();
$msg = '数据编辑失败!';
if(!$res) $this->result($msg, [], 100);
$msg = '保存成功;请提醒财务人员进行审核操作!';
$return = [];
$return['data']= $detail;
$this->result($msg,$return, 200);
}
//删除记录
public function actionDelete()
{
$detail = $this->preUpdate();
if ($detail->deleted != 0) {
$this->result('数据已被删除过,操作无效!', [], 400);
}
/*只有冲红票的且未确认的才能被删除*/
if ($detail->status_code != 2 || $detail->is_chonghong != 1) {
$this->result('只有未被确认的冲红类票据可删除!', [], 400);
}
$res = $this->userPrivilege($this->user_info,'feeOrderEdit',$detail);
if(!$res) $this->result('您没有操作权限!',[],403);
//操作日志处理
$key = 'cwlogs';
$logs = $detail->cwlogs ? json_decode($detail->cwlogs, TRUE) : [];
$log = $this->user_info->username . '于' . date('Y-m-d H:i') . '删除';
array_unshift($logs, $log);
/*修改票据状态*/
$_time = time();
$detail->cwlogs = json_encode($logs, JSON_UNESCAPED_UNICODE);
$detail->update_at = $_time;
$detail->deleted += 1;
$res = $detail->save();
$msg = '删除失败,票据数据保存不成功!';
if(!$res) $this->result($msg, [], 100);
$msg = '票据删除成功!';
$this->result($msg,[], 200);
}
//申请冲红
public function actionApplyChonghong(){
$detail = $this->preUpdate();
$this->preChonghong($detail);
//操作日志处理
$key = 'cwlogs';
$logs = $detail->cwlogs ? json_decode($detail->cwlogs, TRUE) : [];
$log = $this->user_info->username . '于' . date('Y-m-d H:i') . '申请冲红;冲红前状态码[' . $status . ']';
array_unshift($logs, $log);
/*修改票据状态,状态代码:2 */
$_time = time();
$detail->cwlogs = json_encode($logs, JSON_UNESCAPED_UNICODE);
$detail->update_at = $_time;
$detail->status_code = 2;
$res = $detail->save();
if(!$res){
$this->result('申请失败,票据数据保存不成功!', [], 100);
}
$this->result('申请成功,请前往填写冲红单!', [], 200);
}
//终止冲红申请
public function actionStopChonghong(){
$detail = $this->preUpdate();
$status = $detail->status_code;
if ($status != 2) {
$this->result('该单据并非申请冲红状态,无需结束冲红!', [], 100);
}
/*已是冲红票的,不允许再次冲红*/
if ($detail->is_chonghong) {
$this->result('该单据已经是冲红单,无结束冲红操作项!', [], 403);
}
$res = $this->userPrivilege($this->user_info,'feeOrderEdit',$detail);
if(!$res) $this->result('您没有操作权限!',[],403);
//操作日志处理
$key = 'cwlogs';
$logs = $detail->cwlogs ? json_decode($detail->cwlogs, TRUE) : [];
$log = $this->user_info->username . '于' . date('Y-m-d H:i') . '结束冲红申请;';
array_unshift($logs, $log);
/*修改票据状态,状态代码:-2 */
$_time = time();
$detail->cwlogs = json_encode($logs, JSON_UNESCAPED_UNICODE);
$detail->update_at = $_time;
$detail->status_code = -2;
$res = $detail->save();
if(!$res){
$this->result('申请失败,票据数据保存不成功!', [], 100);
}
$this->result('结束冲红操作成功!', [], 200);
}
//冲红票据保存
public function actionSaveChonghong(){
$post = $this->postdata;
$pid = $this->pid;
$cid = (int)$post['chonghong_id'] ?? 0;
if(!$cid) $this->result('未指定要冲红的票据');
$AcFeeModel = new AcFeeOrder();
$feeOrder = $AcFeeModel->findOne($cid);
if(!$feeOrder) $this->result('未找到要冲红的票据');
if ($feeOrder->pid != $pid) {
$this->result('非本平台票据,不可继续操作',[],403);
}
if ($feeOrder->deleted != 0) {
$this->result('票据已标记删除,不可继续操作',[],400);
}
if ($feeOrder->status_code != 2) {
//检查原票据单是否仍为待冲红状态
$this->result('原费用单不是待冲红状态,不可继续操作!',[],400);
}
$res = $this->userPrivilege($this->user_info,'feeOrderEdit',$feeOrder);
if(!$res) $this->result('您没有该费用单的操作权限,请联系制单人或管理员!',[],403);
//关联运单校验
$AcOrder = new AcOrder();
$order = $AcOrder->findOne($feeOrder->order_id);
if (!$order) {
$this->result('关联运单数据异常,不可继续操作!',[],400);
}
$_time = time();
//屏蔽频繁操作
$where = [];
$where[] = 'and';
$where[] = ['=', 'pid', $pid];
$where[] = ['=', 'deleted', 0];
$where[] = ['=', 'chonghong_id', $cid];
$where[] = ['=', 'is_chonghong', 1];
$AcFeeOrder = clone $AcFeeModel;
$res = $AcFeeOrder->find()->where($where)->orderby('create_at ASC')->one();
if ($res) {
$t = $_time - $res->create_at;
if ($t < 60) {
$return['msg'] = '操作太频繁,同1冲红申请在1分钟内仅可提交一次!';
$this->result('操作太频繁,同一冲红单在1分钟内仅可提交一次!',[],403);
}
}
//预先复制部分原票据的数据
$data = [];
$data['pid'] = $pid;
$data['is_chonghong'] = 1;
$data['chonghong_id'] = $cid;
$data['create_at'] = $_time;
$data['update_at'] = $_time;
$data['status_code'] = 2;
$data['create_by'] = $this->user_id;
$data['order_id'] = $feeOrder->order_id;
//冲红金额
$cols = ['money1', 'money2', 'money3']; //金额换算
$is_minus = FALSE;
//考虑是否有负值情况
if (isset($post['money1']) && (int)$post['money1'] < 0) {
$is_minus = TRUE;
} else if (isset($post['money2']) && (int)$post['money2'] < 0) {
$is_minus = TRUE;
} else if (isset($post['money3']) && (int)$post['money3'] < 0) {
$is_minus = TRUE;
}
foreach ($cols as $key) {
if (isset($post[$key]) && $post[$key] != '') {
$money[$key] = abs((int)$post[$key]); //取绝对值
} else {
$money[$key] = 0;
}
}
//角、分 数值必须个位数
if ($money['money2']) {
$money['money2'] = min($money['money2'], 9);
}
if ($money['money3']) {
$money['money3'] = min($money['money3'], 9);
}
$data['fee'] = 100 * $money['money1'] + 10 * $money['money2'] + $money['money3']; //需冲红金额
if ($is_minus) {
$data['fee'] = 0 - $data['fee'];
}
//补充说明
//图片组处理
$key = 'thumbs';
$imgs = [];
if (isset($post[$key]) && !empty($post[$key])) {
$imgs = $post[$key]; //数组格式
$imgs = array_unique($imgs);
}
$data[$key] = json_encode($imgs, JSON_UNESCAPED_UNICODE);
//操作日志处理
$key = 'logs';
$logs = [];
if (isset($post[$key]) && $post[$key] != '') {
$log = $this->user_info->username . '于' . date('Y-m-d H:i') . '备注-' . htmlspecialchars($post[$key]);
}
array_unshift($logs, $log);
$data['cwlogs'] = json_encode($logs, JSON_UNESCAPED_UNICODE);
//保存数据
$model = clone $AcFeeModel;
foreach ($data as $key => $val) {
$model->$key = $val;
}
$res = $model->insert();
if(!$res) $this->result('保存失败,请稍后再试!',[],100);
$id = $model->attributes['id']; //获取插入后id
$msg = '保存成功;可提醒财务人员进行审核操作!';
$this->result($msg,['id'=>$id],200);
}
//财务审核
public function actionCaiwu()
{
$detail = $this->preUpdate();
if ($detail->is_chonghong == 1 && $detail->status_code == -2) {
$this->result('该单据为已冲红票据,不可编辑修改!', [], 403);
}
$res = $this->userPrivilege($this->user_info,'feeOrderEdit',$detail);
if(!$res) $this->result('您没有操作权限!',[],403);
$is_pay_send = isset($post['is_pay_send']) ? 1 : 0;
$is_pay_receive = isset($post['is_pay_receive']) ? 1 : 0;
if ($is_pay_send && $is_pay_receive) {
$this->result('支付发生地为二选一,起运地或目的地请选择其中一个!', [], 100);
}
//校验财务验证码
$vcode = $post['vcode'] ?? null;
if(!$vcode) $this->result('填写财务操作验证码才能操作!', [], 100);
$res = $this->vcodeCwCheck($vcode);
if(!$res['res']) $this->result($res['err'], [], 100);
//操作日志处理
$key = 'logs';
$logs = $detail->cwlogs ? json_decode($detail->cwlogs, TRUE) : [];
if (isset($post[$key]) && $post[$key] != '') {
$log = $this->user_info->username . '于' . date('Y-m-d H:i') . '批复-' . htmlspecialchars($post[$key]);
} else {
$log = $this->user_info->username . '于' . date('Y-m-d H:i') . '进行了审核操作';
}
array_unshift($logs, $log);
$detail->cwlogs = json_encode($logs, JSON_UNESCAPED_UNICODE);
$_time = time();
$detail->update_at = $_time;
$status = $this->getStatus();
$statusCode = $detail->status_code;
$requireArr = $this->getPayStatusRequireArr();
/*驳回
*要求状态为 待确认、申请冲红
*/
if (isset($post['disagree'])) {
$this->cwDisagree($detail);
}
/*确认但不入账
*要求状态为 待确认、驳回
*/
if (isset($post['agree99'])) {
$this->cwAgreeNotIn($detail);
}
/*确认并且入账
*要求状态为 待确认、驳回、仅确认不入账
*/
if (isset($post['agree1'])) {
$this->cwAgreeIn($detail,$is_pay_send);
}
/*确认冲红
*要求状态为 申请冲红、标记冲红单、有冲红单关联
*/
if (isset($post['agree-2'])) {
$this->cwAgreeOut($detail);
}
}
private function search(){
$pid = $this->pid;
$oid = Yii::$app->request->get('oid');
$model = new AcFeeOrder();
$where = [];
$where[] = ['=', 'pid', $pid];
if($oid){
$where[] = ['=', 'order_id', $oid];
}
$post = $this->postdata;
$search = $post['search'] ?? [];
$search['sn'] = isset($search['sn']) ? trim($search['sn']) : '';
if ($search['sn']) {
$where[] = ['=', 'sn', $search['sn']];
}
$where[] = ['=','is_chonghong',0];
$where[] = ['=', 'deleted', 0];
$data = $model->find()->where($where);
$pages = new Pagination(['totalCount' => $data->count(), 'pageSize' => $this->pageSize]);
$res = $data->offset($pages->offset)->limit($pages->limit)->orderby('pay_at DESC')->all();
return ['res'=>$res,'query'=>$data];
}
/*
* 数据更新前的预检查,返回对应关联数据
* 必须确保get与post数据中均包含需更新的数据id且一致
* */
private function preUpdate()
{
$id = (int)Yii::$app->request->get('id');
if(!$id) $this->result('请求错误,未携带ID参数');
$post = $this->postdata;
if($post['id'] != $id) $this->result('传参id与请求数据不匹配',[],403);
$model = new AcFeeOrder();
$res = $model->findOne($id);
if(!$res) $this->result('未查询到相应数据',[],404);
if($res->pid != $this->pid) $this->result('非本平台数据,不允许操作',[],401);
return $res;
}
/*
* 数据保存前的预检查(查重、参数校验等)
* 要保存的数据[],直接从post中取出
* @op,操作类型(add,edit……)
* @detail, 编辑模式下,要修改的数据对象
* 校验机制:
* 编辑数据时,必须用get方式传入参数id,并与post进来的数据id进行比对,只有一致时才能继续;
* 查重:禁止录入重复数据
* 返回:校验重组后的数据
* */
private function preSave($op,$detail=null)
{
$post = $this->postdata;
$data = [];
$_time = time();
$oid = (int)$post['order_id'] ?? 0;
//格式化数据
$_thumbs = $_logs = [];
//目标键=》POST键
switch ($op) {
case 'add':
if(!$oid || $oid != $post['order_id']) $this->result('未关联运单,禁止操作',[],403);
$AcOrder = new AcOrder();
$order = $AcOrder->findOne($oid);
if (!$order) {
$this->result('未找到关联运单,请检查并重新选择运单!', [], 404);
}
$data['order_id'] = $oid;
$data['create_by'] = $this->user_id;
$data['create_at'] = $_time;
$data['update_at'] = $_time;
break;
case 'edit':
$id = (int)Yii::$app->request->get('id');
$_id = (int)$post['id'];
if($id != $_id) $this->result('id参数不匹配,请检查');
if($oid != $detail->order_id) $this->result('不允许更改运单关联,请检查');
if (isset($detail->logs)) {
$_logs = json_decode($detail->logs, TRUE);
}
if (isset($detail->thumbs)) {
$_thumbs = json_decode($detail->thumbs, TRUE);
}
$data['update_at'] = $_time;
break;
}
$data['pid'] = $this->pid;
//格式化数据 为空的项则不修改
$cols = ['pay_from' => '付款方', 'pay_to' => '收款人'];
foreach ($cols as $key => $ti) {
if (isset($post[$key]) && $post[$key] != '') {
$data[$key] = trim($post[$key]);
} else {
$msg = $ti . '不能为空,请检查并填写';
$this->result($msg, [], 100);
}
}
$key = 'paytype';
if (isset($post[$key]) && $post[$key] != '') {
$data[$key] = (int)$post[$key];
} else {
$msg = '支付方式必须选择,请检查';
$this->result($msg, [], 100);
}
$cols = ['money1', 'money2', 'money3']; //金额换算,元角分
$is_minus = FALSE;
//考虑是否有负值情况
if (isset($post['money1']) && (int)$post['money1'] < 0) {
$is_minus = TRUE;
} else if (isset($post['money2']) && (int)$post['money2'] < 0) {
$is_minus = TRUE;
} else if (isset($post['money3']) && (int)$post['money3'] < 0) {
$is_minus = TRUE;
}
foreach ($cols as $key) {
if (isset($post[$key]) && $post[$key] != '') {
$money[$key] = abs((int)$post[$key]); //取绝对值
} else {
$money[$key] = 0;
}
}
//角、分 数值必须个位数
if ($money['money2']) {
$money['money2'] = min($money['money2'], 9);
}
if ($money['money3']) {
$money['money3'] = min($money['money3'], 9);
}
$data['fee'] = 100 * $money['money1'] + 10 * $money['money2'] + $money['money3'];
if ($is_minus) {
$data['fee'] = 0 - $data['fee'];
}
//支付流水号
$key = 'sn';
if (isset($post[$key]) && $post[$key] != '') {
$data[$key] = trim($post[$key]);
}
//图片组处理
$key = 'thumbs';
$imgs = [];
if (isset($post[$key]) && !empty($post[$key])) {
$imgs = $post[$key]; //数组格式
$imgs = array_unique($imgs);
}
if ($imgs) {
if ($_thumbs) {
$imgs = array_merge($imgs, $_thumbs);
$imgs = array_unique($imgs);
}
}
if (!$imgs) {
$msg = '支付凭证截图必须上传,请检查';
$this->result($msg, [], 100);
}
$data[$key] = json_encode($imgs, JSON_UNESCAPED_UNICODE);
//操作日志处理
$key = 'logs';
$logs = [];
if (isset($post[$key]) && $post[$key] != '') {
$data['remark'] = isset($post[$key]) ? htmlspecialchars($post[$key]) : '';
$log = $this->user_info->username . '于' . date('Y-m-d H:i') . '备注-' . htmlspecialchars($post[$key]);
} else {
$log = $this->user_info->username . '于' . date('Y-m-d H:i') . '进行了调整';
}
if ($_logs) {
$logs = $_logs;
}
array_unshift($logs, $log);
$data['cwlogs'] = json_encode($logs, JSON_UNESCAPED_UNICODE);
return $data;
}
/*
* 预冲红,校验数据
* @detail 待校验的冲红票据对象
* */
private function preChonghong($detail){
$status = $detail->status_code;
if($detail->deleted != 0){
$this->result('该单据已标记删除,不可继续操作!', [], 100);
}
if ($status == 0 || $status == -1) {
//TD:后期考虑将单据引入 删除流程(且删除需财务权限)
$this->result('该单据尚未通过财务审核,无需冲红!', [], 100);
}
if ($status == 99) {
$this->result('该单据仅确认并不入库,无需冲红!', [], 100);
}
/*已是冲红票的,不允许再次冲红*/
if ($detail->is_chonghong) {
$this->result('该单据已经是冲红单,不允许多次冲红操作!', [], 403);
}
//关联运单校验
$oid = $detail->order_id;
if (!$oid) {
$this->result('申请失败,未关联运单数据,暂不允许操作!', [], 403);
}
$AcOrder = new AcOrder();
$order = $AcOrder->findOne($oid);
if (!$order) {
$this->result('申请失败,关联运单数据异常,暂不允许操作!', [], 403);
}
}
//支付方式
private function getPaytypes(){
$payTypes = Yii::$app->params['Paytype'];
return $payTypes;
}
//费用单据审核状态
private function getPayStatus(){
$status = Yii::$app->params['PayStatus'];
return $status;
}
//费用单支付状态在财审时的前置状态要求
private function getPayStatusRequireArr(){
$arr = Yii::$app->params['PayStatusRequireArr'];
return $arr;
}
private function showFee($fee){
$detail = $fee->toArray();
$logs = isset($detail['cwlogs']) ? json_decode($detail['cwlogs'], TRUE) : [];
$detail['logs'] = '';
if ($logs) {
foreach ($logs as $log) {
$detail['logs'] .= $log . "\r\n";
}
}
if ($detail['fee'] < 0) {
//如果是支出类单据,先默认支付发生地为起运地
$detail['is_pay_send'] = 1;
}
//金额转换
$money = (int)($detail['fee'] / 100);
$detail['money1'] = $money;
$detail['money2'] = (int)(($detail['fee'] - $money * 100) / 10);
$detail['money3'] = $detail['fee'] - $detail['money1'] * 100 - $detail['money2'] * 10;
//转换一下角分的正负值
$detail['money2'] = abs($detail['money2']);
$detail['money3'] = abs($detail['money3']);
return $detail;
}
/*
* 财务审核:驳回
* @detail,单据详情
* */
private function cwDisagree($detail){
$status = $this->getStatus();
$statusCode = $detail->status_code;
$requireArr = $this->getPayStatusRequireArr();
if (!in_array($statusCode, $requireArr['-1'])) {
$_status = $status[$statusCode] ?? '未知';
$msg = '当前状态为' . $_status . ';不可做驳回操作!';
$this->result($msg,[],400);
}
$detail->status_code = -1; //驳回状态
$res = $detail->save();
if (!$res) {
$msg = '操作失败,单据数据更新没有成功!';
$this->result($msg,[],100);
}
$msg = '操作完成,费用单据已经驳回!';
$this->result($msg,[],0);
}
/*确认但不入账
*要求状态为 待确认、驳回
*/
private function cwAgreeNotIn($detail){
$status = $this->getStatus();
$statusCode = $detail->status_code;
$requireArr = $this->getPayStatusRequireArr();
if (!in_array($statusCode, $requireArr['99'])) {
$_status = $status[$statusCode] ?? '未知';
$msg = '当前状态为' . $_status . ';不可确认!';
$this->result($msg,[],400);
}
if ($detail->is_chonghong == 1) {
$msg = '当前为冲红票据,只支持“确认冲红”、“驳回”两种操作!';
$this->result($msg,[],400);
}
$detail->status_code = 99; //确认但不入账
//查询关联运单并更新运单数据
$oid = $detail->order_id;
$orderModel = new AcOrder();
$order = $orderModel->findOne($oid);
if (!$order) {
$res = $detail->save();
if ($res) {
$msg = '操作完成!但关联运单不存在';
$this->result($msg,[],0);
} else {
$msg = '操作失败!';
$this->result($msg,[],100);
}
}
$fee = round($detail->fee / 100, 2); //换算为 元 单位
//是否为佣金
$is_commission = $post['is_commission'] ?? 0;
if ($is_commission) {
$commission = $fee;
if (!$order->commission || $order->commission < 0) {
$msg = '关联运单未计提佣金,不可标记为佣金单据,请检查操作!';
$this->result($msg,[],400);
}
if ($commission > 0) {
$msg = '确认入账情况下,佣金必须为负值(即单据为支出单),请检查操作!';
$this->result($msg,[],400);
}
}
$res = $detail->save();
if (!$res) {
$msg = '操作失败,单据数据更新没有成功!';
$this->result($msg,[],100);
}
$msg = '操作完成,费用单据已更新!';
$this->result($msg,[],100);
}
/*确认但不入账
*要求状态为 待确认、驳回
* @isPaySend 是否起运地付款
*/
private function cwAgreeIn($detail,$isPaySend=false){
$status = $this->getStatus();
$statusCode = $detail->status_code;
$requireArr = $this->getPayStatusRequireArr();
if (!in_array($statusCode, $requireArr['1'])) {
$_status = $status[$statusCode] ?? '未知';
$msg = '当前状态为' . $_status . ';不可确认入账!';
$this->result($msg,[],400);
}
if ($detail->is_chonghong == 1) {
$msg = '当前为冲红票据,只支持“确认冲红”、“驳回”两种操作!';
$this->result($msg,[],400);
}
//查询关联运单并更新运单数据
$oid = $detail->order_id;
$orderModel = new AcOrder();
$order = $orderModel->findOne($oid);
if (!$order) {
$detail->status_code = 99; //仅确认不入账
$res = $detail->save();
if ($res) {
$msg = '操作完成!但关联运单不存在,入账失败,已自动变更为“仅确认不入账”!';
$this->result($msg,[],0);
} else {
$msg = '操作失败!';
$this->result($msg,[],100);
}
}
/*财务未确认运单的,无法入账*/
if (!$order->is_cwqr) {
$msg = '关联运单尚未通过财务审核,无法做相应的费用票据入账操作!';
$this->result($msg,[],400);
}
/*运单标记为完结的,无法入账*/
if ($order->is_over) {
$msg = '关联运单已经标记完结,无法再做相应的费用票据入账操作!';
$this->result($msg,[],400);
}
$detail->status_code = 1; //确认入账
$fee = round($detail->fee / 100, 2); //换算为 元 单位
//是否为佣金
$is_commission = $post['is_commission'] ?? 0;
if ($is_commission) {
$commission = $fee;
if (!$order->commission || $order->commission < 0) {
$msg = '关联运单未计提佣金,不可标记为佣金单据,请检查操作!';
$this->result($msg,[],400);
}
if (!$order->commission_left || $order->commission_left < 0) {
$msg = '关联运单已无剩余待支付佣金,不可作佣金入账,请检查操作!';
$this->result($msg,[],400);
}
if ($commission > 0) {
$msg = '确认入账情况下,佣金必须为负值(即单据为支出单),请检查操作!';
$this->result($msg,[],400);
}
if (($commission + $order->commission_left) > ($order->commission + Yii::$app->params['DefaultCommissionMoreMax'])) {
$msg = '本次佣金超出关联运单中记录核定的佣金金额,且超出部分超过了平台容错上限(' . Yii::$app->params['DefaultCommissionMoreMax'] . '元),入账失败,请检查操作!';
$this->result($msg,[],400);
}
}
$res = $detail->save();
if(!$res){
$msg = '操作失败,单据数据更新没有成功!';
$this->result($msg,[],100);
}
//同步更新运单数据
$_time = time();
$order->update_at = $_time;
$payids = [];
$_k = FALSE;
if ($isPaySend) {
$_k = 'pay_send_pids';
} else {
$_k = 'pay_receive_pids';
}
if ($_k) {
$payids = json_decode($order->$_k, TRUE);
if (!$payids) {
$payids = [$detail->id];
} else {
array_unshift($payids, $detail->id);
array_unique($payids);
}
$order->$_k = json_encode($payids, JSON_UNESCAPED_UNICODE);
}
if ($is_commission) {
$order->commission_left = $order->commission_left + $commission;
}
/*
*负值支出时,总收入减少 支出增加
*正值收入时,总收入增加 支出不变
*总收入income始终加fee
*/
$order->income += $detail->fee;
if($detail->fee<0){
$order->expense -= $detail->fee;
}
//写入到订单数据中
$res = $order->save();
if (!$res) {
$detail->status_code = 0;
$res2 = $detail->save();
$msg = '操作结束,但关联运单的数据更新没有成功,已修改本费用单状态为初始状态;可以晚些再重新尝试操作!';
if(!$res2) $msg = '操作结束,但关联运单的数据更新没有成功,冲红费用单状态重置也失败;请联系技术管理员修复后再重新尝试操作!';
$this->result($msg,[],100);
}
$msg = '操作完成,运单数据与费用单据均已更新!';
$this->result($msg,[],200);
}
/*确认冲红
*要求状态为 申请冲红、标记冲红单、有冲红单关联
*/
private function cwAgreeOut($detail,$isPaySend=false){
$status = $this->getStatus();
$statusCode = $detail->status_code;
$requireArr = $this->getPayStatusRequireArr();
$_time = time();
if (!in_array($statusCode, $requireArr['2'])) {
$_status = $status[$statusCode] ?? '未知';
$msg = '当前状态为' . $_status . ';不可冲红!';
$this->result($msg,[],400);
}
if ($detail->is_chonghong != 1) {
$msg = '当前并非冲红票据,不支持“确认冲红”操作!';
$this->result($msg,[],400);
}
if(!$detail->chonghong_id){
$msg = '标记了冲红但未关联相应的对冲票据,不能继续操作!';
$this->result($msg,[],400);
}
//校验对冲票据有效性
$AcFeeModel = new AcFeeOrder();
$chonghong = $AcFeeModel->findOne($detail->chonghong_id);
if (!$chonghong) {
$msg = '关联对冲票据的数据获取异常,操作中断!';
$this->result($msg,[],400);
}
if ($chonghong->deleted) {
$msg = '关联对冲票据已标记删除,不能继续操作!';
$this->result($msg,[],400);
}
//查询关联运单并更新运单数据
$oid = $detail->order_id;
$orderModel = new AcOrder();
$order = $orderModel->findOne($oid);
if (!$order) {
$msg = '关联运单数据获取异常,操作中断!';
$this->result($msg,[],400);
}
$detail->status_code = -2; //确认冲红
$cols = ['money1', 'money2', 'money3'];
$is_minus = FALSE;
foreach ($cols as $key) {
if (isset($post[$key]) && $post[$key] != '') {
if ((int)$post[$key] < 0) {
$is_minus = TRUE; //考虑是否有负值情况
}
$money[$key] = abs((int)$post[$key]); //取绝对值
} else {
$money[$key] = 0;
}
}
//角、分 数值必须个位数
if ($money['money2']) {
$money['money2'] = min($money['money2'], 9);
}
if ($money['money3']) {
$money['money3'] = min($money['money3'], 9);
}
$ch_fee = 100 * $money['money1'] + 10 * $money['money2'] + $money['money3']; //要冲红的金额
if ($is_minus) {
$ch_fee = 0 - $ch_fee;
}
$detail->fee = $ch_fee; //本票据实际冲红金额
$detail->update_at = $_time;
$fee = $chonghong->fee - $ch_fee; //差值即为原单据更新后的金额
$fee = round($fee / 100, 2); //换算为 元 单位
//是否为佣金
$is_commission = $post['is_commission'] ?? 0;
if ($is_commission) {
$commission = $fee;
if (!$order->commission || $order->commission < 0) {
$msg = '关联运单未计提佣金,不可标记为佣金单据,请检查操作!';
$this->result($msg,[],400);
}
if (!$order->commission_left || $order->commission_left < 0) {
$msg = '关联运单已无剩余待支付佣金,不可作佣金入账,请检查操作!';
$this->result($msg,[],400);
}
if ($commission > 0) {
$msg = '确认入账情况下,佣金必须为负值(即单据为支出单),请检查操作!';
$this->result($msg,[],400);
}
if (($commission + $order->commission_left) > ($order->commission + Yii::$app->params['DefaultCommissionMoreMax'])) {
$msg = '本次佣金超出关联运单中记录核定的佣金金额,且超出部分超过了平台容错上限(' . Yii::$app->params['DefaultCommissionMoreMax'] . '元),入账失败,请检查操作!';
$this->result($msg,[],400);
}
}
$res = $detail->save();
if (!$res) {
$msg = '冲红失败,单据数据更新没有成功!';
$this->result($msg,[],100);
}
//避免不可预知的逻辑错误,原对冲票状态仍然应标记为申请冲红状态
$chonghong->status_code = 2;
//对冲票为原始数据,不作其他修改
$chonghong->save();
//同步订单处理
$order->update_at = $_time;
if ($is_commission) {
$order->commission_left = $order->commission_left + $commission;
}
/*
*负值支出时,总收入减少 支出增加
*正值收入时,总收入增加 支出不变
*总收入income始终加fee
*/
$order->income += $detail->fee;
if($detail->fee<0){
$order->expense -= $detail->fee;
}
//写入到订单数据中
$res = $order->save();
if (!$res) {
$detail->status_code = 0;
$res2 = $detail->save();
$msg = '操作结束,但关联运单的数据更新没有成功,已修改本费用单状态为初始状态;可以晚些再重新尝试操作!';
if(!$res2) $msg = '操作结束,但关联运单的数据更新没有成功,冲红费用单状态重置也失败;请联系技术管理员修复后再重新尝试操作!';
$this->result($msg,[],100);
}
$msg = '操作完成,运单数据与费用单据均已更新!';
$this->result($msg,[],200);
}
}