修正共用合同合作方及归属主体,支持个人实名签署 #288
@ -56,7 +56,7 @@ class CourierAgreementSignatures extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
if (in_array($requestedType, ['account-proof', 'account-change', 'entity-change', 'cooperation-contract', 'authorization'], true)
|
||||
if (in_array($requestedType, ['account-proof', 'account-change', 'entity-change', 'cooperation-contract', 'authorization', 'shared-contract'], true)
|
||||
&& ! $request->filled('counterparty_signer_type')) {
|
||||
// Existing integrations omit this field and historically meant an
|
||||
// enterprise signer, so keep that behavior as the compatibility default.
|
||||
@ -64,9 +64,6 @@ class CourierAgreementSignatures extends Controller
|
||||
}
|
||||
|
||||
$data = $request->validate($this->rules(), [
|
||||
'operator_name.required_if' => $requestedType === 'shared-contract'
|
||||
? '请填写合同主体经办人的 E 签宝实名认证姓名。'
|
||||
: '请填写快递方经办人的 E 签宝实名认证姓名。',
|
||||
'secondary_operator_name.required_if' => '请填写我方 E 签宝账号绑定的实名认证姓名。',
|
||||
]);
|
||||
$type = $data['document_type'];
|
||||
@ -74,6 +71,12 @@ class CourierAgreementSignatures extends Controller
|
||||
throw ValidationException::withMessages(['authorization_items' => '授权委托书至少选择一项授权事项。']);
|
||||
}
|
||||
if ($type === 'shared-contract') {
|
||||
$data['contract_partner_name'] = trim((string) $data['contract_partner_name']);
|
||||
if ($data['counterparty_signer_type'] === 'person') {
|
||||
$data['operator_name'] = $data['contract_partner_name'];
|
||||
} elseif (blank($data['operator_name'] ?? null)) {
|
||||
throw ValidationException::withMessages(['operator_name' => '请填写物流商归属企业经办人的 E 签宝实名认证姓名。']);
|
||||
}
|
||||
$sharedCouriers = collect($data['shared_courier_names'] ?? [])
|
||||
->map(static fn ($name): string => trim((string) $name))
|
||||
->filter()
|
||||
@ -371,9 +374,9 @@ class CourierAgreementSignatures extends Controller
|
||||
'esign_account' => ['required', 'string', 'max:255'],
|
||||
'secondary_esign_account' => ['required_if:document_type,cooperation-contract,authorization', 'nullable', 'string', 'max:255'],
|
||||
'secondary_operator_name' => ['nullable', 'string', 'min:2', 'max:100'],
|
||||
'operator_name' => ['required_if:document_type,shared-contract', 'nullable', 'string', 'min:2', 'max:100'],
|
||||
'operator_name' => ['nullable', 'string', 'min:2', 'max:100'],
|
||||
'counterparty_organization_name' => ['required_if:document_type,account-proof,account-change', 'nullable', 'string', 'min:2', 'max:255'],
|
||||
'counterparty_signer_type' => ['required_if:document_type,account-proof,account-change,entity-change,cooperation-contract,authorization', 'nullable', 'in:organization,person'],
|
||||
'counterparty_signer_type' => ['required_if:document_type,account-proof,account-change,entity-change,cooperation-contract,authorization,shared-contract', 'nullable', 'in:organization,person'],
|
||||
'secondary_signer_type' => ['nullable', 'in:organization,person'],
|
||||
'entity_change_old_company_deregistered' => ['nullable', 'boolean'],
|
||||
'archive_mode' => ['required', 'in:auto,manual'],
|
||||
@ -393,7 +396,7 @@ class CourierAgreementSignatures extends Controller
|
||||
'entity_change_date' => ['required_if:document_type,entity-change', 'date'],
|
||||
'changed_company_name' => ['required_if:document_type,entity-change', 'string', 'max:255'],
|
||||
'changed_company_start_date' => ['required_if:document_type,entity-change', 'date'],
|
||||
'contract_partner_name' => ['required_if:document_type,shared-contract', 'string', 'max:255'],
|
||||
'contract_partner_name' => ['required_if:document_type,shared-contract', 'string', 'min:2', 'max:255'],
|
||||
'shared_courier_names' => ['nullable', 'array', 'min:1'],
|
||||
'shared_courier_names.*' => ['required', 'string', 'max:255'],
|
||||
'shared_courier_name' => ['nullable', 'string', 'max:255'],
|
||||
|
||||
@ -288,13 +288,14 @@ final class CourierAgreementSignatureService
|
||||
$payload = $signature->payload ?? [];
|
||||
|
||||
if ($signature->document_type === 'shared-contract') {
|
||||
$isPerson = ($payload['counterparty_signer_type'] ?? 'organization') === 'person';
|
||||
if (blank($signature->operator_name)) {
|
||||
throw new RuntimeException('请填写合同主体经办人的 E 签宝实名认证姓名。');
|
||||
throw new RuntimeException('请填写物流商归属主体签署人的 E 签宝实名认证姓名。');
|
||||
}
|
||||
|
||||
return [[
|
||||
'signer_type' => 1,
|
||||
'organization_name' => $signature->organization_name,
|
||||
'signer_type' => $isPerson ? 0 : 1,
|
||||
'organization_name' => $isPerson ? null : $signature->organization_name,
|
||||
'operator_name' => $signature->operator_name,
|
||||
'operator_account' => $signature->operator_account,
|
||||
]];
|
||||
|
||||
@ -1447,7 +1447,7 @@
|
||||
<option value="account-proof" data-title="收款帐户资料证明" data-name="收款账户证明" data-code="TPL-ACCOUNT-CERT-V2" data-file="收款账户证明文件.doc" data-description="原文件:收款账户证明文件.doc;快递公司盖章" selected>收款账户证明</option>
|
||||
<option value="account-change" data-title="收款帐户资料变更证明" data-name="收款账户变更" data-code="TPL-ACCOUNT-CHANGE-V1" data-file="收款账户变更证明.doc" data-description="原文件:收款账户变更证明.doc;快递公司盖章">收款账户变更</option>
|
||||
<option value="entity-change" data-title="公司主体变更证明" data-name="公司主体变更" data-code="TPL-ENTITY-CHANGE-V1" data-file="公司主体变更证明.docx" data-description="原文件:公司主体变更证明.docx;变更前、变更后公司分别签字盖章">公司主体变更</option>
|
||||
<option value="shared-contract" data-title="证明" data-name="共用合同证明" data-code="TPL-SHARED-CONTRACT-V1" data-file="共用合同证明.docx" data-description="两家快递共用一份合同、打款资料、签字人及法人均相同,需法人签字+公司盖章">共用合同证明</option>
|
||||
<option value="shared-contract" data-title="证明" data-name="共用合同证明" data-code="TPL-SHARED-CONTRACT-V1" data-file="共用合同证明.docx" data-description="物流商归属企业盖章确认共用合同及结算主体;也可选择个人实名签署">共用合同证明</option>
|
||||
<option value="cooperation-contract" data-title="服务协议" data-name="合作合同" data-code="TPL-COOPERATION-CONTRACT-V1" data-file="保丟不保损-合同发快递2024.8.doc" data-description="原文件:保丟不保损-合同发快递2024.8.doc;甲乙双方签署盖章">合作合同</option>
|
||||
<option value="authorization" data-title="授权委托书" data-name="授权委托书" data-code="TPL-AUTHORIZATION-V1" data-file="授权委托书(快递).docx" data-description="原文件:授权委托书(快递).docx;委托方和受托方签署">授权委托书</option>
|
||||
<option value="quote-confirmation" data-title="报价确认单" data-name="报价确认单" data-code="TPL-QUOTE-CONFIRMATION-V1" data-file="报价确认单(报价版本快照).pdf" data-description="绑定已审核报价版本;快递方单方签署">报价确认单</option>
|
||||
@ -1619,9 +1619,9 @@
|
||||
|
||||
<div class="agreement-form-grid" data-template-fields="shared-contract" hidden>
|
||||
<div class="agreement-field">
|
||||
<label for="agreement-contract-partner">合同主体(企业全称) <span class="agreement-required" aria-hidden="true">*</span></label>
|
||||
<input class="agreement-control" id="agreement-contract-partner" name="contract_partner_name" type="text" placeholder="填写合同主体在 E 签宝认证的企业全称" autocomplete="organization" required>
|
||||
<p class="agreement-help">该企业作为本证明的签署主体,名称须与 E 签宝企业认证一致。</p>
|
||||
<label for="agreement-contract-partner"><span data-shared-subject-label>物流商归属主体(企业全称)</span> <span class="agreement-required" aria-hidden="true">*</span></label>
|
||||
<input class="agreement-control" id="agreement-contract-partner" name="contract_partner_name" type="text" placeholder="填写物流商归属企业在 E 签宝认证的全称" autocomplete="organization" required>
|
||||
<p class="agreement-help" data-shared-subject-help>由该企业盖章确认快递归属及结算主体;正文合作方使用上方的我方公司全称。</p>
|
||||
</div>
|
||||
<div class="agreement-field agreement-field--full">
|
||||
<label>共用合同物流商(快递名称,可多个) <span class="agreement-required" aria-hidden="true">*</span></label>
|
||||
@ -1635,7 +1635,7 @@
|
||||
<span class="material-icons-outlined" aria-hidden="true">add</span>
|
||||
<span>添加共用公司</span>
|
||||
</button>
|
||||
<p class="agreement-help">填写归属上述合同主体、共用合同和打款资料的快递名称,可添加多个。</p>
|
||||
<p class="agreement-help">填写归属上述企业或个人、共用合同和打款资料的快递名称,可添加多个。</p>
|
||||
</div>
|
||||
<div class="agreement-field agreement-field--full">
|
||||
<label for="agreement-shared-note">备注</label>
|
||||
@ -1812,11 +1812,12 @@
|
||||
|
||||
<article class="agreement-preview-paper" data-template-preview="shared-contract" hidden>
|
||||
<h3>证明</h3>
|
||||
<p>与 <span class="agreement-preview-value" data-preview-bind="contractPartnerName">待填写</span> 合作的 <span class="agreement-preview-value" data-preview-bind="sharedCourierName">待填写</span> 共同用一份合同,打款资料为同一份资料,同一个签字人以及同一个法人!</p>
|
||||
<p>与 <span class="agreement-preview-value" data-preview-bind="company">{{ $agreementCompanyName }}</span> 合作的 <span class="agreement-preview-value" data-preview-bind="sharedCourierName">待填写</span>,均归属于 <span class="agreement-preview-value" data-preview-bind="contractPartnerName">待填写</span>,共用一份合同及同一份打款资料,合同签署及结算主体均为 <span class="agreement-preview-value" data-preview-bind="contractPartnerName">待填写</span>。</p>
|
||||
<p>特此证明!</p>
|
||||
<p data-preview-shared-note hidden>备注:<span class="agreement-preview-value" data-preview-bind="sharedNote">待填写</span></p>
|
||||
<div class="agreement-preview-signature">
|
||||
<p>法人签字并公司盖章:</p>
|
||||
<p><span data-preview-bind="sharedSignerLabel">确认企业</span>:<span class="agreement-preview-value" data-preview-bind="contractPartnerName">待填写</span></p>
|
||||
<p data-shared-organization-signature>法人签字并公司盖章:</p>
|
||||
<p>日期:<span data-preview-bind="signatureDate">{{ now()->format('Y年n月j日') }}</span></p>
|
||||
</div>
|
||||
<p class="agreement-preview-page-number">第 1 页 / 共 1 页</p>
|
||||
@ -1903,7 +1904,7 @@
|
||||
<tr><td>收款账户变更</td><td>收款账户变更证明.doc</td><td>本地映射 V1</td><td>变更日期、旧账户、停用日期、新账户、生效日期</td><td>快递公司</td><td><span class="agreement-status agreement-status--warning">公司盖章</span></td><td><button class="agreement-icon-button" type="button" disabled title="E签宝模板尚未创建"><span class="material-icons-outlined" aria-hidden="true">settings</span></button></td></tr>
|
||||
<tr><td>收款账户证明</td><td>收款账户证明文件.doc</td><td>本地映射 V1</td><td>生效日期、开户名称、开户银行、银行帐户</td><td>快递公司</td><td><span class="agreement-status agreement-status--warning">公司盖章</span></td><td><button class="agreement-icon-button" type="button" disabled title="E签宝模板尚未创建"><span class="material-icons-outlined" aria-hidden="true">settings</span></button></td></tr>
|
||||
<tr><td>公司主体变更</td><td>公司主体变更证明.docx</td><td>本地映射 V1</td><td>变更前后名称、变更日期、启用日期</td><td>变更前、变更后公司</td><td><span class="agreement-status agreement-status--warning">法人签字并盖章</span></td><td><button class="agreement-icon-button" type="button" disabled title="E签宝模板尚未创建"><span class="material-icons-outlined" aria-hidden="true">settings</span></button></td></tr>
|
||||
<tr><td>共用合同证明</td><td>共用合同证明.docx</td><td>本地映射 V1</td><td>合同合作方、共用合同快递、证明日期</td><td>快递公司法人</td><td><span class="agreement-status agreement-status--warning">法人签字并盖章</span></td><td><button class="agreement-icon-button" type="button" disabled title="E签宝模板尚未创建"><span class="material-icons-outlined" aria-hidden="true">settings</span></button></td></tr>
|
||||
<tr><td>共用合同证明</td><td>共用合同证明.docx</td><td>本地映射 V1</td><td>我方合作公司、物流商归属主体、共用合同快递、证明日期</td><td>物流商归属企业或个人</td><td><span class="agreement-status agreement-status--warning">企业盖章或个人签字</span></td><td><button class="agreement-icon-button" type="button" disabled title="E签宝模板尚未创建"><span class="material-icons-outlined" aria-hidden="true">settings</span></button></td></tr>
|
||||
<tr><td>合作合同</td><td>保丟不保损-合同发快递2024.8.doc</td><td>本地映射 V1</td><td>甲乙方名称、甲乙方电话、协议起止日期</td><td>甲方、乙方</td><td><span class="agreement-status agreement-status--warning">双方签字盖章</span></td><td><button class="agreement-icon-button" type="button" disabled title="E签宝模板尚未创建"><span class="material-icons-outlined" aria-hidden="true">settings</span></button></td></tr>
|
||||
<tr><td>授权委托书</td><td>授权委托书(快递).docx</td><td>本地映射 V1</td><td>委托双方、授权事项、往来方、有效期</td><td>委托方、受托方</td><td><span class="agreement-status agreement-status--warning">双方签署</span></td><td><button class="agreement-icon-button" type="button" disabled title="E签宝模板尚未创建"><span class="material-icons-outlined" aria-hidden="true">settings</span></button></td></tr>
|
||||
<tr><td>报价确认单</td><td>报价版本快照</td><td>本地映射 V1</td><td>版本号、快递公司、报价类型、有效期、报价明细</td><td>快递公司</td><td><span class="agreement-status agreement-status--warning">快递方签章</span></td><td><button class="agreement-icon-button" type="button" disabled title="E签宝模板尚未创建"><span class="material-icons-outlined" aria-hidden="true">settings</span></button></td></tr>
|
||||
@ -2737,14 +2738,16 @@
|
||||
var entityChange = templateType === 'entity-change';
|
||||
var cooperationContract = templateType === 'cooperation-contract';
|
||||
var authorization = templateType === 'authorization';
|
||||
var sharedContract = templateType === 'shared-contract';
|
||||
var formerCompanyDeregistered = entityChange && entityChangeDeregisteredInput && entityChangeDeregisteredInput.checked;
|
||||
var signerTypeFieldVisible = accountAgreement || cooperationContract || authorization;
|
||||
var signerTypeFieldVisible = accountAgreement || cooperationContract || authorization || sharedContract;
|
||||
var accountSignerTypeInput = accountSignerTypeInputs.find(function (input) {
|
||||
return input.checked;
|
||||
});
|
||||
var accountSignerType = accountSignerTypeInput ? accountSignerTypeInput.value : 'organization';
|
||||
var accountSignerIsPerson = accountAgreement && accountSignerType === 'person';
|
||||
var otherSignerIsPerson = (cooperationContract || authorization) && accountSignerType === 'person';
|
||||
var sharedSignerIsPerson = sharedContract && accountSignerType === 'person';
|
||||
var trusteeSignerTypeInput = authorizationSecondarySignerTypeInputs.find(function (input) {
|
||||
return input.checked;
|
||||
});
|
||||
@ -2771,7 +2774,7 @@
|
||||
: '填写对方在 E 签宝认证的企业全称';
|
||||
}
|
||||
if (operatorNameInput) {
|
||||
var needsPrimaryOperator = templateType === 'shared-contract' || (accountAgreement && !accountSignerIsPerson) || entityChange || ((cooperationContract || authorization) && !otherSignerIsPerson);
|
||||
var needsPrimaryOperator = (sharedContract && !sharedSignerIsPerson) || (accountAgreement && !accountSignerIsPerson) || entityChange || ((cooperationContract || authorization) && !otherSignerIsPerson);
|
||||
operatorNameInput.disabled = !needsPrimaryOperator;
|
||||
operatorNameInput.required = needsPrimaryOperator;
|
||||
operatorNameInput.placeholder = formerCompanyDeregistered
|
||||
@ -2788,8 +2791,8 @@
|
||||
|
||||
}
|
||||
if (operatorHelp) {
|
||||
operatorHelp.textContent = templateType === 'shared-contract'
|
||||
? '填写合同主体经办人的真实姓名,须与上方 E 签宝账号实名认证一致;快递名称填写在下方物流商名单。'
|
||||
operatorHelp.textContent = sharedContract
|
||||
? '填写物流商归属企业经办人的真实姓名,须与上方 E 签宝账号实名认证一致;快递名称填写在下方物流商名单。'
|
||||
: '仅用于 E 签宝身份核验,不是收款人姓名;收款人姓名请填写在下方账户资料中。';
|
||||
}
|
||||
if (accountSignerLabel) {
|
||||
@ -2887,8 +2890,15 @@
|
||||
}
|
||||
|
||||
if (templateType === 'shared-contract') {
|
||||
setPreviewValue('contractPartnerName', fieldValue('[name="contract_partner_name"]', companyName));
|
||||
var sharedSubjectInput = root.querySelector('[name="contract_partner_name"]');
|
||||
setText('[data-shared-subject-label]', sharedSignerIsPerson ? '物流商归属主体(个人实名)' : '物流商归属主体(企业全称)');
|
||||
sharedSubjectInput.autocomplete = sharedSignerIsPerson ? 'name' : 'organization';
|
||||
sharedSubjectInput.placeholder = sharedSignerIsPerson ? '填写该个人在 E 签宝实名认证的姓名' : '填写物流商归属企业在 E 签宝认证的全称';
|
||||
setText('[data-shared-subject-help]', sharedSignerIsPerson ? '由该个人实名签字确认快递归属及结算主体;正文合作方使用上方的我方公司全称。' : '由该企业盖章确认快递归属及结算主体;正文合作方使用上方的我方公司全称。');
|
||||
setPreviewValue('contractPartnerName', fieldValue('[name="contract_partner_name"]', '待填写'));
|
||||
setPreviewValue('sharedCourierName', sharedCourierValues().join('、') || '待填写');
|
||||
setPreviewValue('sharedSignerLabel', sharedSignerIsPerson ? '确认人(个人签字)' : '确认企业');
|
||||
root.querySelector('[data-shared-organization-signature]').hidden = sharedSignerIsPerson;
|
||||
var sharedNote = fieldValue('[name="shared_note"]', '');
|
||||
setPreviewValue('sharedNote', sharedNote || '待填写');
|
||||
var sharedNotePreview = root.querySelector('[data-preview-shared-note]');
|
||||
|
||||
@ -83,12 +83,20 @@
|
||||
<div class="sign"><p>变更前公司法人签字盖公章:{!! $mixedText($payload['former_company_name']) !!}(签署人:{!! $mixedText($payload['former_legal_representative'] ?? '') !!})</p><p>变更后公司法人签字盖公章:{!! $mixedText($payload['changed_company_name']) !!}(签署人:{!! $mixedText($payload['secondary_operator_name'] ?? '') !!})</p><p>日期:{!! $mixedText($signatureDate) !!}</p></div>
|
||||
@endif
|
||||
@elseif ($type === 'shared-contract')
|
||||
<p>与 {!! $mixedText($payload['contract_partner_name'] ?? '') !!} 合作的 {!! $mixedText($sharedCourierText) !!} 共同用一份合同,打款资料为同一份资料,同一个签字人以及同一个法人!</p>
|
||||
<p>与 {!! $mixedText($payload['company_full_name'] ?? $signature->company_full_name) !!} 合作的 {!! $mixedText($sharedCourierText) !!},均归属于 {!! $mixedText($payload['contract_partner_name'] ?? '') !!},共用一份合同及同一份打款资料,合同签署及结算主体均为 {!! $mixedText($payload['contract_partner_name'] ?? '') !!}。</p>
|
||||
<p>特此证明!</p>
|
||||
@if (filled($payload['shared_note'] ?? null))
|
||||
<p>备注:{!! $mixedText($payload['shared_note']) !!}</p>
|
||||
@endif
|
||||
<div class="sign"><p>法人签字并公司盖章:</p><p>日期:{!! $mixedText($signatureDate) !!}</p></div>
|
||||
<div class="sign">
|
||||
@if (($payload['counterparty_signer_type'] ?? 'organization') === 'person')
|
||||
<p>确认人(个人签字):{!! $mixedText($payload['contract_partner_name'] ?? '') !!}</p>
|
||||
@else
|
||||
<p>确认企业:{!! $mixedText($payload['contract_partner_name'] ?? '') !!}</p>
|
||||
<p>法人签字并公司盖章:</p>
|
||||
@endif
|
||||
<p>日期:{!! $mixedText($signatureDate) !!}</p>
|
||||
</div>
|
||||
@elseif ($type === 'cooperation-contract')
|
||||
@include('business.partials.cooperation-contract', ['mode' => 'pdf', 'payload' => $payload, 'signatureDate' => $signatureDate])
|
||||
@else
|
||||
|
||||
@ -352,15 +352,19 @@ class AgreementSigningPageTest extends FeatureTestCase
|
||||
->assertSeeText('变更后,原公司的各项事宜由变更后的公司继续执行')
|
||||
->assertSee('data-template-fields="shared-contract"', false)
|
||||
->assertSee('data-template-preview="shared-contract"', false)
|
||||
->assertSeeText('合同合作方')
|
||||
->assertSeeText('合同主体(企业全称)')
|
||||
->assertSeeText('我方合作公司')
|
||||
->assertSeeText('物流商归属主体(企业全称)')
|
||||
->assertSee('物流商归属主体(个人实名)', false)
|
||||
->assertSee('data-preview-bind="sharedSignerLabel"', false)
|
||||
->assertSee('data-shared-organization-signature', false)
|
||||
->assertSeeText('共用合同物流商(快递名称,可多个)')
|
||||
->assertSeeText('填写合同主体经办人的真实姓名,须与上方 E 签宝账号实名认证一致')
|
||||
->assertSeeText('填写物流商归属企业经办人的真实姓名,须与上方 E 签宝账号实名认证一致')
|
||||
->assertSee('name="shared_courier_names[]"', false)
|
||||
->assertSee('data-shared-courier-add', false)
|
||||
->assertSeeText('添加共用公司')
|
||||
->assertSeeText('备注')
|
||||
->assertSeeText('共同用一份合同,打款资料为同一份资料')
|
||||
->assertSeeText('共用一份合同及同一份打款资料')
|
||||
->assertSeeText('合同签署及结算主体均为')
|
||||
->assertSee('data-template-fields="cooperation-contract"', false)
|
||||
->assertSee('data-template-preview="cooperation-contract"', false)
|
||||
->assertSee('data-template-preview="quote-confirmation"', false)
|
||||
|
||||
@ -460,23 +460,24 @@ class CourierAgreementSignatureWorkflowTest extends FeatureTestCase
|
||||
'courier_name' => '新北中通',
|
||||
'document_type' => 'shared-contract',
|
||||
'signing_subject' => $this->company->name,
|
||||
'company_full_name' => $this->company->name,
|
||||
'company_full_name' => '常州电优闪供应链管理有限公司',
|
||||
'signature_date' => '2026-09-21',
|
||||
'signing_deadline' => now()->addDays(7)->toDateString(),
|
||||
'esign_account' => '13800138000',
|
||||
'operator_name' => '张经理',
|
||||
'archive_mode' => 'auto',
|
||||
'contract_partner_name' => '快递公司甲',
|
||||
'shared_courier_names' => ['快递公司乙', '快递公司丙'],
|
||||
'contract_partner_name' => '宿迁天枢物流科技有限公司',
|
||||
'shared_courier_names' => ['常州圆通其他', '常州圆通-丁楼'],
|
||||
'shared_note' => '请在3个工作日内完成签章。',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$signature = CourierAgreementSignature::query()->firstOrFail();
|
||||
$this->assertSame(['快递公司乙', '快递公司丙'], $signature->payload['shared_courier_names']);
|
||||
$this->assertSame('快递公司甲', $signature->organization_name);
|
||||
$this->assertSame(['常州圆通其他', '常州圆通-丁楼'], $signature->payload['shared_courier_names']);
|
||||
$this->assertSame('宿迁天枢物流科技有限公司', $signature->organization_name);
|
||||
$this->assertSame('organization', $signature->payload['counterparty_signer_type']);
|
||||
$this->assertSame('张经理', $signature->operator_name);
|
||||
$this->assertSame('快递公司乙', $signature->payload['shared_courier_name']);
|
||||
$this->assertSame('常州圆通其他', $signature->payload['shared_courier_name']);
|
||||
$this->assertSame('请在3个工作日内完成签章。', $signature->payload['shared_note']);
|
||||
$pdf = Storage::disk('uploads')->get($signature->source_pdf_path);
|
||||
$this->assertStringStartsWith('%PDF-', $pdf);
|
||||
@ -488,9 +489,13 @@ class CourierAgreementSignatureWorkflowTest extends FeatureTestCase
|
||||
'signatureDate' => '2026年9月21日',
|
||||
'fontPath' => str_replace('\\', '/', resource_path('fonts/DroidSansFallback.ttf')),
|
||||
])->render();
|
||||
foreach (['快递公司甲', '快递公司乙', '快递公司丙', '请在3个工作日内完成签章。'] as $text) {
|
||||
foreach (['常州电优闪供应链管理有限公司', '宿迁天枢物流科技有限公司', '常州圆通其他', '常州圆通-丁楼', '请在3个工作日内完成签章。'] as $text) {
|
||||
$this->assertStringContainsString($text, strip_tags($html));
|
||||
}
|
||||
$this->assertStringContainsString('与 常州电优闪供应链管理有限公司 合作的', strip_tags($html));
|
||||
$this->assertStringNotContainsString('与 宿迁天枢物流科技有限公司 合作的', strip_tags($html));
|
||||
$this->assertStringContainsString('均归属于 宿迁天枢物流科技有限公司', strip_tags($html));
|
||||
$this->assertStringContainsString('确认企业:宿迁天枢物流科技有限公司', strip_tags($html));
|
||||
|
||||
Http::assertSent(function (ClientRequest $request): bool {
|
||||
if ($request->url() !== 'https://smlopenapi.esign.test/v3/sign-flow/create-by-file') {
|
||||
@ -499,12 +504,65 @@ class CourierAgreementSignatureWorkflowTest extends FeatureTestCase
|
||||
|
||||
return count($request->data()['signers'] ?? []) === 1
|
||||
&& data_get($request->data(), 'signers.0.signerType') === 1
|
||||
&& data_get($request->data(), 'signers.0.orgSignerInfo.orgName') === '快递公司甲'
|
||||
&& data_get($request->data(), 'signers.0.orgSignerInfo.orgName') === '宿迁天枢物流科技有限公司'
|
||||
&& data_get($request->data(), 'signers.0.orgSignerInfo.transactorInfo.psnAccount') === '13800138000'
|
||||
&& data_get($request->data(), 'signers.0.orgSignerInfo.transactorInfo.psnInfo.psnName') === '张经理';
|
||||
});
|
||||
}
|
||||
|
||||
public function test_shared_contract_can_be_confirmed_by_a_person_without_an_enterprise_seal(): void
|
||||
{
|
||||
$this->fakeEsign();
|
||||
$payload = [
|
||||
'idempotency_key' => 'shared-contract-person',
|
||||
'courier_name' => '常州圆通其他',
|
||||
'document_type' => 'shared-contract',
|
||||
'signing_subject' => $this->company->name,
|
||||
'company_full_name' => '常州电优闪供应链管理有限公司',
|
||||
'signature_date' => '2026-09-21',
|
||||
'signing_deadline' => now()->addDays(7)->toDateString(),
|
||||
'esign_account' => '13800138000',
|
||||
'archive_mode' => 'auto',
|
||||
'counterparty_signer_type' => 'person',
|
||||
'contract_partner_name' => '张三',
|
||||
'shared_courier_names' => ['常州圆通其他', '常州圆通-丁楼'],
|
||||
];
|
||||
|
||||
$this->loginAs()->post(route('business.courier-agreement-signatures.store'), $payload)->assertRedirect();
|
||||
$signature = CourierAgreementSignature::query()->firstOrFail();
|
||||
$this->assertSame('person', $signature->payload['counterparty_signer_type']);
|
||||
$this->assertSame('张三', $signature->organization_name);
|
||||
$this->assertSame('张三', $signature->operator_name);
|
||||
$this->assertSame($payload['shared_courier_names'], $signature->payload['shared_courier_names']);
|
||||
$this->assertStringStartsWith('%PDF-', Storage::disk('uploads')->get($signature->source_pdf_path));
|
||||
$html = view('business.pdf.courier-agreement', [
|
||||
'signature' => $signature,
|
||||
'type' => $signature->document_type,
|
||||
'title' => $signature->documentLabel(),
|
||||
'payload' => $signature->payload,
|
||||
'signatureDate' => '2026年9月21日',
|
||||
'fontPath' => str_replace('\\', '/', resource_path('fonts/DroidSansFallback.ttf')),
|
||||
])->render();
|
||||
$this->assertStringContainsString('与 常州电优闪供应链管理有限公司 合作的', strip_tags($html));
|
||||
$this->assertStringContainsString('均归属于 张三', strip_tags($html));
|
||||
$this->assertStringContainsString('确认人(个人签字):张三', strip_tags($html));
|
||||
$this->assertStringNotContainsString('法人', $html);
|
||||
$this->assertStringNotContainsString('公司盖章', $html);
|
||||
|
||||
Http::assertSent(function (ClientRequest $request): bool {
|
||||
return $request->url() === 'https://smlopenapi.esign.test/v3/sign-flow/create-by-file'
|
||||
&& count($request->data()['signers'] ?? []) === 1
|
||||
&& data_get($request->data(), 'signers.0.signerType') === 0
|
||||
&& data_get($request->data(), 'signers.0.psnSignerInfo.psnAccount') === '13800138000'
|
||||
&& data_get($request->data(), 'signers.0.psnSignerInfo.psnInfo.psnName') === '张三'
|
||||
&& data_get($request->data(), 'signers.0.orgSignerInfo') === null;
|
||||
});
|
||||
|
||||
$this->post(route('business.courier-agreement-signatures.store'), $payload)->assertRedirect();
|
||||
$this->assertDatabaseCount('business_courier_agreement_signatures', 1);
|
||||
Http::assertSentCount(4);
|
||||
}
|
||||
|
||||
public function test_shared_contract_rejects_missing_real_name_without_creating_a_task_or_remote_request(): void
|
||||
{
|
||||
Http::fake();
|
||||
@ -532,6 +590,19 @@ class CourierAgreementSignatureWorkflowTest extends FeatureTestCase
|
||||
->assertStatus(422)
|
||||
->assertJsonValidationErrors('operator_name');
|
||||
|
||||
$payload['counterparty_signer_type'] = 'person';
|
||||
unset($payload['operator_name']);
|
||||
$payload['contract_partner_name'] = ' ';
|
||||
$this->postJson(route('business.courier-agreement-signatures.store'), $payload)
|
||||
->assertStatus(422)
|
||||
->assertJsonValidationErrors('contract_partner_name');
|
||||
|
||||
$payload['contract_partner_name'] = '张三';
|
||||
$payload['counterparty_signer_type'] = 'invalid';
|
||||
$this->postJson(route('business.courier-agreement-signatures.store'), $payload)
|
||||
->assertStatus(422)
|
||||
->assertJsonValidationErrors('counterparty_signer_type');
|
||||
|
||||
$this->assertDatabaseCount('business_courier_agreement_signatures', 0);
|
||||
Http::assertNothingSent();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user