diff --git a/app/service/invoice/InvoiceIssuanceService.php b/app/service/invoice/InvoiceIssuanceService.php index eda805d..f6d5c1d 100644 --- a/app/service/invoice/InvoiceIssuanceService.php +++ b/app/service/invoice/InvoiceIssuanceService.php @@ -15,6 +15,8 @@ use Endroid\QrCode\Label\Font\NotoSans; use Endroid\QrCode\Writer\PngWriter; use fast\FuncException; use think\App; +use think\facade\Log; +use think\facade\Request; class InvoiceIssuanceService { @@ -87,14 +89,7 @@ class InvoiceIssuanceService switch ($project_id) { case 1: - $FeeService = new FeeService($pucode); - $param = [ - 'startCostYearMonth' => $expire_date, - 'endCostYearMonth' => $expire_date, - 'PaymentStatus' => 2, - ]; - - $ComputeDetail = $FeeService->getComputeDetail($param); + $ComputeDetail = self::getFeeComputeDetail($pucode, $expire_date); if ($ComputeDetail['MsgID'] != 1) { throw new FuncException($errorMsg); } @@ -108,17 +103,46 @@ class InvoiceIssuanceService } } + /** + * + * @param $pucode + * @param $expire_date + * @return mixed + * @throws FuncException + */ + public static function getFeeComputeDetail($pucode, $expire_date) + { + $FeeService = new FeeService($pucode); + + $param = [ + 'startCostYearMonth' => $expire_date, + 'endCostYearMonth' => $expire_date, + 'PaymentStatus' => 2, + ]; + + return $FeeService->getComputeDetail($param); + } + /** * 获取二维码 + * @param $id * @return string + * @throws FuncException + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException */ - public static function getQrCode(): string + public static function getQrCode($id): string { //$ChinaTaxes = new ChinaTaxes(); + $InvoiceIssuanceData = (new InvoiceIssuanceData)->where(['invoice_issuance_id' => $id, 'status' => 1])->find(); + if (!$InvoiceIssuanceData) { + throw new FuncException('不存在现在地址'); + } - $codeUrl = 'http://www.longazi.vip/blog/22';//$ChinaTaxes->downTaxPaymentProve(); - + $url = Request::url(); + $codeUrl = $url . $InvoiceIssuanceData['pdf_filepath']; $result = Builder::create() ->writer(new PngWriter()) @@ -190,6 +214,16 @@ class InvoiceIssuanceService $feeUsers['bdznsrsbh'] = $bdznsrsbh; + // 获取用户应收费信息 + $FeeComputeDetail = self::getFeeComputeDetail($pucode, date("Ym", $invoiceIssuance['expire_time'])); + if ($FeeComputeDetail['MsgID'] != 1) { + throw new FuncException($FeeComputeDetail); + } + + $feeUsers['jsyj'] = $FeeComputeDetail['WaterAmount']; + $feeUsers['zsfsmc'] = $FeeComputeDetail['chargetype']; + $feeUsers['jfrq'] = $FeeComputeDetail['WaterPayDate']; + // 保存 $ChinaTaxes = new ChinaTaxes($feeUsers, $invoiceDate); $savingDetailedData = $ChinaTaxes->savingDetailedData(); @@ -243,6 +277,8 @@ class InvoiceIssuanceService $pdfFilepath = $this->savePdfFile($deCompress['data']['pdfdata']); (new InvoiceIssuanceData())->saveData($invoiceIssuance['id'], $bdznsrsbh, $jsyj, $assetID, $pdfFilepath); + + (new InvoiceIssuance())->where('id', $invoiceIssuance['id'])->save(['status' => 4]); } else if ($realTimeProcessing['code'] == 302) { // 加工失败 @@ -257,11 +293,14 @@ class InvoiceIssuanceService // 保存用户异常状态 $ycms = $queryUploadErrorData['mxGrid']['sbMxsjVOList']['ycms']; // 数据异常描述 (new InvoiceIssuanceData())->saveField($invoiceIssuance['id'], 'ycms', $ycms); + + // 开票失败 + (new InvoiceIssuance())->where('id', $invoiceIssuance['id'])->save(['status' => 3]); //throw new FuncException('加工失败流程待定!'); } return true; } catch (\Exception $e) { - + $this->writeLog($e); return $e->getMessage(); } } @@ -275,7 +314,14 @@ class InvoiceIssuanceService $feeUsers = $this->getFeeUserData($invoiceIssuance['pucode']); + $InvoiceIssuanceWhere = ['invoice_issuance_id' => $invoiceIssuance['id'], 'status' => 1]; + $InvoiceIssuanceData = (new InvoiceIssuanceData())->where($InvoiceIssuanceWhere)->find(); + if (!$InvoiceIssuanceData) { + throw new FuncException('上次发起数据不存在'); + } + $bdznsrsbh = '91440300772709730N'; // 被代征纳税人识别号 + $sbpch = $InvoiceIssuanceData['sbpch']; $ChinaTaxes = new ChinaTaxes($feeUsers, []); @@ -285,23 +331,23 @@ class InvoiceIssuanceService throw new FuncException($identityCheck['Yy']);// 返回校验不通过原因 } - $InvoiceIssuanceWhere = ['invoice_issuance_id' => $invoiceIssuance['id']]; - $InvoiceIssuanceData = (new InvoiceIssuanceData())->where($InvoiceIssuanceWhere)->find(); - - // - $ChinaTaxes->collectionDetails($bdznsrsbh, $InvoiceIssuanceData['sbpch']); + // 代征明细数据虚拟户更正接口 + $ChinaTaxes->collectionDetails($bdznsrsbh, $sbpch); // 作废 3.2 - $ChinaTaxes->invalidEntrustCollection($InvoiceIssuanceData['sbpch']); + $ChinaTaxes->invalidEntrustCollection($sbpch); // 修改作废 (new InvoiceIssuanceData())->saveField($invoiceIssuance['id'], 'status', 0, 2); - $this->IssueAnInvoice($invoiceIssuance); + $result = $this->IssueAnInvoice($invoiceIssuance); + if ($result !== true) { + throw new \Exception($result); + } return true; } catch (\Exception $e) { - + $this->writeLog($e); return $e->getMessage(); } } @@ -349,7 +395,16 @@ class InvoiceIssuanceService $sbpch = $daiZhengSummaryQuery['cxwjbList']['cxwjbVO']['sbpch']; // 申报批次号 $ydzse = $daiZhengSummaryQuery['cxwjbList']['cxwjbVO']['ydzse']; // 应代征税额 + $ChinaTaxes->daiZhengSummaryReport($ydzse); + + } + public function writeLog($e) + { + Log::record('Exception message: ' . $e->getMessage()); + Log::record('Exception file: ' . $e->getFile()); + Log::record('Exception line: ' . $e->getLine()); + Log::record('Exception trace: ' . $e->getTraceAsString()); } /** diff --git a/app/service/webService/ChinaTaxes.php b/app/service/webService/ChinaTaxes.php index 58dbb79..d295236 100644 --- a/app/service/webService/ChinaTaxes.php +++ b/app/service/webService/ChinaTaxes.php @@ -12,8 +12,6 @@ class ChinaTaxes protected $puCodeUser; // accessToken protected $accessToken; - // 接入端交易请求唯一标识 - protected $reqId; // 接入渠道标识(ID) protected $channelId; // 平台为接入渠道统一分配的密码 @@ -22,13 +20,11 @@ class ChinaTaxes protected $apiUrl; // 密钥 protected $my = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuc3JzYmgiOiI2MjAxMDQ3NzQ0MTk4NVgiLCJpc3MiOiJTU1NIR1oiLCJkanhoIjoiMTAxMTQ0MDMwMDAwMjY0NzE2NzQiLCJzdGFydFRpbWUiOiIiLCJ1bmRUaW11IjoiMjAyMi0wNi0zMCAxODowNDo0MSIsImV4cCI6MTY1NjU4MzQ4MSwic3BqZyI6IjEifQ.Ho0H43DxSGDmydHamMABRampNaNTu3K5vJwTJzoLAMA'; - // xml组合数据类型 + // xml组合返回数据类型:1 = 返回字段标签格式、2 = 字段标签 + ns2: + 加密、3 = 字段标签 + 加密 protected $xmlType = 1; - // 参数类型 - protected $xml = 1; // 申请发票信息 protected $invoiceIssuance; - // 加密XML名 + // 加密XML Base标签的key protected $xmlKey = '01'; /** @@ -39,7 +35,6 @@ class ChinaTaxes $this->puCodeUser = $data; $this->apiUrl = env('taxes.api_url'); - $this->reqId = $this->getReqId(); // 接入端交易请求唯一标识,长度 32 位,5 秒内不得重复,否则抛出异常:交易请求唯一标识重复。 $this->channelId = env('taxes.channel_id'); // 接入渠道标识(ID) $this->channelSecret = env('taxes.channel_secret'); // 平台为接入渠道统一分配的密码,只有身份验证接口需要 @@ -60,7 +55,7 @@ class ChinaTaxes $this->accessToken = $tax_access_token; } else { $param = [ - 'reqId' => $this->reqId, // 接入端交易请求唯一标识,长度 32 位,5 秒内不得重复,否则抛出异常:交易请求唯一标识重复。 + 'reqId' => $this->getReqId(), // 接入端交易请求唯一标识,长度 32 位,5 秒内不得重复,否则抛出异常:交易请求唯一标识重复。 'sid' => 'bizAccessLogin', // 调用的接口名称,固定为“bizAccessLogin” 'channelId' => $this->channelId, // 接入渠道标识(ID) 'channelSecret' => $this->channelSecret, // 平台为接入渠道统一分配的密码,只有身份验证接口需要 @@ -99,7 +94,7 @@ class ChinaTaxes 'accessToken' => $this->accessToken,// 访问令牌,由调用身份验证接口获取 'timestamp' => time(),// unix 时间戳 'data' => [ - 'bizXml' => $this->bizXml($body) + 'bizXml' => !empty($body) ? $this->bizXml($body) : '' ], ]; return $data; @@ -123,7 +118,7 @@ class ChinaTaxes 'zsxmDm' => '30433',// 征收项目代码 'zspmDm' => '304331300',// 征收品目代码 'zszmDm' => '',// 征收子目代码 - 'jsyj' => '11.11',// 计税依据,保留两位小数 + 'jsyj' => $this->puCodeUser['jsyj'],// 计税依据,保留两位小数 'sl1' => '',// 税率,可手工填写,不填则默认系统自动计算,保留两位小数 'ynse' => '',// 应纳税额,可手工填写,不填则默认系统自动计算,保留两位小数 'ydzse' => '',// 应代征税额,可手工填写,不填则默认系统自动计算,保留两位小数 @@ -139,21 +134,21 @@ class ChinaTaxes 'xmbm' => 'T435',// 项目编码 'username' => $userName,// 用户名称(同一个批次,同一个用户编号下,值相同) 'nbyhbm' => $this->puCodeUser['UserCode'],// 用户编号 - 'jldwmc' => '立方米',// 单位 - 'sl' => '100',// 数量 - 'zxbz1' => '10',// 标准 + 'jldwmc' => '',// 单位 + 'sl' => '',// 数量 + 'zxbz1' => '',// 标准 'skyhmc' => $this->puCodeUser['BankName'],// 托收银行(同一个批次,同一个用户编号下,值相同) 'yhzh' => $this->puCodeUser['BankAccountCode'],// 银行账号(同一个批次,同一个用户编号下,值相同) - 'zsfsmc' => '手工转账',// 缴费方式(同一个批次,同一个用户编号下,值相同) - 'tjsd' => '2022-11-01至2022-11-30',// 收费时段(同一个批次,同一个用户编号下,值相同) - 'jfyj1' => '测试',// 计费依据(同一个批次,同一个用户编号下,值相同) - 'yhje' => '10.00',// 优惠金额 - 'hjje' => '990.00',// 合计金额 - 'jfrq' => '2022-11-30',// 缴费时间(同一个批次,同一个用户编号下,值相同) - 'lxfs' => '测试',// 联系方式(同一个批次,同一个用户编号下,值相同) - 'lxdz' => '测试',// 送票地址(同一个批次,同一个用户编号下,值相同) - 'remark' => '测试',// 备注(同一个批次,同一个用户编号下,值相同) - 'bz' => '测试',// 备注信息(同一个批次,同一个用户编号下,值相同) + 'zsfsmc' => $this->puCodeUser['zsfsmc'],// 缴费方式(同一个批次,同一个用户编号下,值相同) + 'tjsd' => $this->invoiceIssuance['skssqq'] . '至' . $this->invoiceIssuance['skssqz'],// 收费时段(同一个批次,同一个用户编号下,值相同) + 'jfyj1' => $this->puCodeUser['jsyj'],// 计费依据(同一个批次,同一个用户编号下,值相同) + 'yhje' => '0.00',// 优惠金额 + 'hjje' => $this->puCodeUser['jsyj'],// 合计金额 + 'jfrq' => $this->puCodeUser['jfrq'],// 缴费时间(同一个批次,同一个用户编号下,值相同) + 'lxfs' => '',// 联系方式(同一个批次,同一个用户编号下,值相同) + 'lxdz' => '',// 送票地址(同一个批次,同一个用户编号下,值相同) + 'remark' => '',// 备注(同一个批次,同一个用户编号下,值相同) + 'bz' => '',// 备注信息(同一个批次,同一个用户编号下,值相同) ]; $body = [ @@ -172,7 +167,7 @@ class ChinaTaxes $param = $this->getParamData('SSGZ_GZPT_SZQKL_WTDZDRJK', $body); - $res = $this->resultXml($param); + $res = $this->resultXml($param, 0); if (!isset($res['sbpch'])) { throw new FuncException('未获取到批次号'); } @@ -194,9 +189,11 @@ class ChinaTaxes 'czlx' => 'CX', // 操作类型(CX:查询;JG:加工) ]; + $this->xmlKey = '06'; + $param = $this->getParamData('SSGZ_GZPT_SZQKL_JGWTDZ', $body); - return $this->resultXml($param, '6', 3); + return $this->resultXml($param, 3); } /** @@ -224,7 +221,7 @@ class ChinaTaxes $param = $this->getParamData('SSGZ_GZPT_PZ_SQKJDZJKPZ', $body); - return $this->resultXml($param, '', 1); + return $this->resultXml($param); } /** @@ -242,7 +239,7 @@ class ChinaTaxes $param = $this->getParamData('SSGZ_GZPT_PZ_QUERYDZJKPZSLXX', $body); - $result = $this->resultXml($param, '', 1); + $result = $this->resultXml($param); return [ 'meta' => $result['pzkjxxVO']['meta'], @@ -267,7 +264,7 @@ class ChinaTaxes $result = $this->json_curl(json_encode($param)); - return $this->resultXml($result, '', 1); + return $this->resultXml($result); } /** @@ -291,7 +288,7 @@ class ChinaTaxes $result = $this->json_curl(json_encode($param)); - return $this->resultXml($result, '', 1); + return $this->resultXml($result); } /** @@ -321,7 +318,7 @@ class ChinaTaxes $result = $this->json_curl(json_encode($param)); - return $this->resultXml($result, '7'); + return $this->resultXml($result, 0); } /** @@ -336,32 +333,32 @@ class ChinaTaxes $body = [ 'gzxxList' => [ 'gzxxVO' => [ - 'my' => $this->my // 密钥,数字签名校验和资格校验 + 'nsrlx' => 1, // 2 非自然人、1 自然人 + 'yhbh' => $this->puCodeUser['UserCode'], // 水司的用户编号 + 'nsrsbh' => $nsrsbh, // 传输类型为单位不可以为空 + 'nsrmc' => $this->puCodeUser['ContactName'], // 不可为空 ? + 'zjhm' => $this->puCodeUser['CertificateCode'], // 传输类型为自然人,不可以为空 + 'zjlx' => '201', // 传输类型为自然人,不可以为空,添加证件类型代码 999 + 'gj' => '156', // 国籍 + 'username' => $this->puCodeUser['UserName'], // 用户名称 + 'skyhmc' => $this->puCodeUser['BankName'], // 托收银行 + 'yhzh' => $this->puCodeUser['BankAccountCode'], // 银行账号 + 'lxdz' => $this->puCodeUser['MaillingAddress'], // 用户地址 + 'lxfs' => $this->puCodeUser['Telephone'], // 联系方式 + 'sbpch' => $sbpch, // 申报批次号 ], - 'nsrlx' => 1, // 2 非自然人、1 自然人 - 'yhbh' => $this->puCodeUser['UserCode'], // 水司的用户编号 - 'nsrsbh' => $nsrsbh, // 传输类型为单位不可以为空 - 'nsrmc' => $this->puCodeUser['ContactName'], // 不可为空 ? - 'zjhm' => $this->puCodeUser['CertificateCode'], // 传输类型为自然人,不可以为空 - 'zjlx' => '201', // 传输类型为自然人,不可以为空,添加证件类型代码 999 - 'gj' => '156', // 国籍 - 'username' => $this->puCodeUser['UserName'], // 用户名称 - 'skyhmc' => $this->puCodeUser['BankName'], // 托收银行 - 'yhzh' => $this->puCodeUser['BankAccountCode'], // 银行账号 - 'lxdz' => $this->puCodeUser['MaillingAddress'], // 用户地址 - 'lxfs' => $this->puCodeUser['Telephone'], // 联系方式 - 'sbpch' => $sbpch, // 申报批次号 ], + 'my' => $this->my // 密钥,数字签名校验和资格校验 ]; - $this->xmlType = 2; - $this->xmlKey = '10'; + $this->xmlType = 3; + $this->xmlKey = '10'; $param = $this->getParamData('SSGZ_GZPT_SZQKL_SB_XNHGZ', $body); $result = $this->json_curl(json_encode($param)); - return $this->resultXml($result, '', 1); + return $this->resultXml($result); } /** @@ -379,7 +376,7 @@ class ChinaTaxes $result = $this->json_curl(json_encode($param)); - return $this->resultXml($result, '', 1); + return $this->resultXml($result); } /** @@ -400,7 +397,7 @@ class ChinaTaxes $result = $this->json_curl(json_encode($param)); - return $this->resultXml($result, '', 1); + return $this->resultXml($result); } /** @@ -422,7 +419,7 @@ class ChinaTaxes $result = $this->json_curl(json_encode($param)); - return $this->resultXml($result, '', 1); + return $this->resultXml($result); } /** @@ -444,7 +441,7 @@ class ChinaTaxes $result = $this->json_curl(json_encode($param)); - return $this->resultXml($result, '', 1); + return $this->resultXml($result); } /** @@ -464,7 +461,7 @@ class ChinaTaxes $result = $this->json_curl(json_encode($param)); - return $this->resultXml($result, '', 1); + return $this->resultXml($result); } /** @@ -490,7 +487,7 @@ class ChinaTaxes $result = $this->json_curl(json_encode($param)); - return $this->resultXml($result, '', 1); + return $this->resultXml($result); } /** @@ -514,10 +511,9 @@ class ChinaTaxes /** * 处理 body 报文 * @param $body - * @param int $type * @return string */ - protected function bizXml($body, int $type = 0): string + protected function bizXml($body): string { $xmlKey = $this->xmlKey; $start = ' @@ -526,43 +522,51 @@ xmlns:ns2="http://www.chinatax.gov.cn/dataspec/">'; $start1 = ''; $end = ''; - $this->xmlKey = '01'; - - $xml = ''; - $xml2 = ''; - foreach ($body as $key => $value) { - if (is_array($value)) { - $xml .= "<$key>" . $this->bizXml($value, 1) . ""; - $xml2 .= "" . $this->bizXml($value, 1) . ""; - } else { - $xml .= "<$key>$value"; - $xml2 .= "" . $value . ""; - } - } - - if ($type == 1) { - return $xml; - } + $xml = $this->bizXmlStr($body, $this->xmlType == 2 ? $this->xmlType : 1); // 需要ns2 前后组合 加密返回 if ($this->xmlType == 2) { - $this->xmlType = 1; - return $start1 . $this->enCompressXml($start . $xml2 . $end) . $end; + return $start1 . $this->enCompressXml($start . $xml . $end) . $end; } - // 需要ns2 前后组合 加密返回 if ($this->xmlType == 3) { - $this->xmlType = 1; - return $start1 . $this->enCompressXml($start . $xml . $end) . $end; + $startXml = ' + +'; + $endXml = ''; + $enCompressXml = $this->enCompressXml($startXml . $xml . $endXml); + return $start1 . $enCompressXml . $end; } // 直接返回 - if ($this->xmlType == 1) { - return $xml; - } + return $xml; + } - // 不需要前后组合 - return $xml2; + /** + * 循环处理bizXml数据 + * @param $body + * @param int $type + * @return string + */ + protected function bizXmlStr($body, int $type = 1): string + { + $xml = ''; + foreach ($body as $key => $value) { + if (is_array($value)) { + if ($type == 2) { + $xml .= "" . $this->bizXmlStr($value, $type) . ""; + } else { + $xml .= "<$key>" . $this->bizXmlStr($value, $type) . ""; + } + } else { + if ($type == 2) { + $xml .= "" . $value . ""; + } else { + $xml .= "<$key>$value"; + } + } + } + return $xml; } /** @@ -691,16 +695,19 @@ xmlns:ns2="http://www.chinatax.gov.cn/dataspec/">'; /** * 处理返回的XML数据 * @param $param - * @param string $keyValue * @param int $type * @return array * @throws FuncException */ - protected function resultXml($param, string $keyValue = '1', int $type = 0): array + protected function resultXml($param, int $type = 1): array { - $key = "SZQKLDZSPSB000{$keyValue}ZipBase64ResponsBw"; + $key = "SZQKLDZSPSB00{$this->xmlKey}ZipBase64ResponsBw"; $result = $this->json_curl(json_encode($param)); + // 恢复修改 + $this->xmlKey = '01'; + $this->xmlType = 1; + if (!isset($result['result'])) { if (isset($result['error']['message'])) { throw new FuncException($result['error']['message']); @@ -713,6 +720,9 @@ xmlns:ns2="http://www.chinatax.gov.cn/dataspec/">'; if ($type == 1 && $data['code'] == 302) return $data; throw new FuncException($data['message']); } else if ($type == 1) { + if (isset($data[$key])) { + $data['zipBaseData'] = $this->deCompressXml($data[$key]); + } return $data; }