1.1.27 1、合同新增时添加勾选框 已生效客户订单,若勾选后把合同附件自动带到终版合同附件。

2、合同新增时添加 合同属地标识、合同属地国家/地区、结算币种,合同管理台账添加此三个字段。合同属地标识是其他的税率默认0。
3、合同激活时非大陆合同添加对人民币汇率。
dev
yinq 2 months ago
parent a76bcf1ee4
commit 564653e1e0

@ -49,6 +49,31 @@ export interface ContractInfoVO {
*/
contractDate: string;
/**
* 1 2
*/
contractTerritorialFlag?: string;
/**
* /
*/
contractTerritorialCountry?: string;
/**
* CNY/USD/EUR
*/
settlementCurrency?: string;
/**
*
*/
rmbExchangeRate?: number;
/**
* 1 0
*/
effectiveCustomerOrderFlag?: string;
/**
*
*/
@ -307,6 +332,31 @@ export interface ContractInfoForm extends BaseEntity {
*/
contractDate?: string;
/**
* 1 2
*/
contractTerritorialFlag?: string;
/**
* /
*/
contractTerritorialCountry?: string;
/**
* CNY/USD/EUR
*/
settlementCurrency?: string;
/**
*
*/
rmbExchangeRate?: number;
/**
* 1 0
*/
effectiveCustomerOrderFlag?: string;
/**
*
*/
@ -563,6 +613,31 @@ export interface ContractInfoQuery extends PageQuery {
*/
contractDate?: string;
/**
* 1 2
*/
contractTerritorialFlag?: string;
/**
* /
*/
contractTerritorialCountry?: string;
/**
* CNY/USD/EUR
*/
settlementCurrency?: string;
/**
*
*/
rmbExchangeRate?: number;
/**
* 1 0
*/
effectiveCustomerOrderFlag?: string;
/**
*
*/

@ -18,6 +18,9 @@ export interface ContractLedgerReportVO {
externalContractCode: string;
customerContractCode: string;
contractDate: string;
contractTerritorialFlag: string;
contractTerritorialCountry: string;
settlementCurrency: string;
orderContractCode: string;
projectContractCode: string;
customerName: string;

@ -116,6 +116,46 @@
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合同属地" prop="contractTerritorialFlag">
<div style="display: flex; align-items: center; width: 100%; gap: 12px">
<el-radio-group v-model="form.contractTerritorialFlag" :disabled="isFormDisabled">
<el-radio v-for="dict in contract_territorial_flag" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
</el-radio-group>
<el-select
v-if="form.contractTerritorialFlag === '2'"
v-model="form.contractTerritorialCountry"
placeholder="请选择国家/地区"
:disabled="isFormDisabled"
filterable
clearable
style="flex: 1"
>
<el-option v-for="dict in country_region" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="结算币种" prop="settlementCurrency">
<el-select v-model="form.settlementCurrency" placeholder="请选择结算币种" :disabled="isFormDisabled" clearable>
<el-option v-for="dict in currency_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item label="对人民币汇率" prop="rmbExchangeRate">
<el-input-number
v-model="form.rmbExchangeRate"
:min="0"
:precision="6"
:step="0.0001"
:disabled="isFormDisabled"
placeholder="请输入对人民币汇率"
style="width: 100%"
/>
</el-form-item>
</el-col> -->
<el-col :span="12">
<el-form-item label="付款账户" prop="paymentAccountId">
<el-select v-model="form.paymentAccountId" placeholder="请选择付款账户" :disabled="isFormDisabled"
@ -291,15 +331,32 @@
</el-col>
<el-col :span="12">
<el-form-item label="附件" prop="ossId">
<!-- <el-button type="primary" plain icon="Upload" @click="handleFile"></el-button>-->
<FileUpload
v-model="ossIdString"
:limit="5"
:fileSize="20"
:fileType="['doc', 'docx', 'pdf', 'xls', 'xlsx']"
:disabled="isFormDisabled"
:isShowTip="true"
/>
<div style="display: flex; width: 100%; gap: 16px; align-items: flex-start">
<!-- <el-button type="primary" plain icon="Upload" @click="handleFile"></el-button>-->
<div style="flex: 1; min-width: 0">
<FileUpload
v-model="ossIdString"
:limit="5"
:fileSize="20"
:fileType="['doc', 'docx', 'pdf', 'xls', 'xlsx']"
:disabled="isFormDisabled"
:isShowTip="true"
/>
</div>
<div style="width: 230px; display: flex; flex-direction: column; align-items: flex-start; padding-top: 2px">
<el-checkbox
v-model="form.effectiveCustomerOrderFlag"
true-value="1"
false-value="0"
:disabled="isFormDisabled"
>
<span style="font-weight: 600">已生效客户订单</span>
</el-checkbox>
<div style="color: #909399; font-size: 12px; line-height: 1.4; margin-top: 4px">
无需盖章或签字即刻生效的客户订单
</div>
</div>
</div>
</el-form-item>
</el-col>
</el-row>
@ -400,7 +457,7 @@
<el-table-column label="备注" align="center" prop="remark" min-width="100" />
<el-table-column label="操作" align="center" fixed="right" width="150" v-if="!isFormDisabled">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleEditMaterial(scope.row)"></el-button>
<el-button link type="primary" icon="Edit" @click="handleEditMaterial(scope.row, scope.$index)">编辑</el-button>
<el-button link type="danger" icon="Delete" @click="handleDeleteMaterial(scope.row)"></el-button>
</template>
</el-table-column>
@ -723,7 +780,10 @@ const {
contract_status,
material_flag,
contract_template_flag,
is_framework_contract
is_framework_contract,
contract_territorial_flag,
country_region,
currency_type
} = toRefs<any>(
proxy?.useDict(
'contract_category',
@ -734,7 +794,10 @@ const {
'contract_status',
'material_flag',
'contract_template_flag',
'is_framework_contract'
'is_framework_contract',
'contract_territorial_flag',
'country_region',
'currency_type'
)
);
@ -858,6 +921,7 @@ const materialDialog = reactive({
visible: false,
title: ''
});
const editingMaterialIndex = ref<number | null>(null);
//
const initMaterialFormData: ContractMaterialForm = {
@ -1011,6 +1075,11 @@ const initFormData: ContractInfoFormEx = {
businessDirection: undefined,
contractDeptId: undefined,
contractDate: undefined,
contractTerritorialFlag: '1',
contractTerritorialCountry: undefined,
settlementCurrency: 'CNY',
rmbExchangeRate: 1,
effectiveCustomerOrderFlag: '0',
totalPrice: 0,
oneCustomerId: undefined,
oneRepresent: undefined,
@ -1058,6 +1127,33 @@ const data = reactive<{ form: ContractInfoFormEx; rules: any }>({
contractName: [{ required: true, message: '合同名称不能为空', trigger: 'blur' }],
businessDirection: [{ required: true, message: '业务方向不能为空', trigger: 'blur' }],
contractManagerId: [{ required: true, message: '合同负责人不能为空', trigger: 'blur' }],
contractTerritorialFlag: [{ required: true, message: '合同属地标识不能为空', trigger: 'change' }],
contractTerritorialCountry: [
{
validator: (_rule: any, _value: any, callback: (err?: Error) => void) => {
if (form.value.contractTerritorialFlag === '2' && !form.value.contractTerritorialCountry) {
callback(new Error('合同属地标识为“其他”时,国家/地区不能为空'));
return;
}
callback();
},
trigger: 'change'
}
],
settlementCurrency: [{ required: true, message: '结算币种不能为空', trigger: 'change' }],
rmbExchangeRate: [{ required: true, message: '对人民币汇率不能为空', trigger: 'blur' }],
ossId: [
{
validator: (_rule: any, _value: any, callback: (err?: Error) => void) => {
if (form.value.effectiveCustomerOrderFlag === '1' && !form.value.ossId) {
callback(new Error('已生效客户订单必须上传附件'));
return;
}
callback();
},
trigger: 'change'
}
],
contractTemplateFlag: [{ required: true, message: '合同模板标识不能为空', trigger: 'blur' }],
isFrameworkContract: [{ required: true, message: '请选择关联框架合同', trigger: 'change' }],
frameworkValidPeriod: [
@ -1130,6 +1226,30 @@ watch(
}
);
watch(
() => form.value.contractTerritorialFlag,
(newVal) => {
// 0
initMaterialFormData.taxRate = newVal === '2' ? 0 : 13;
if (newVal === '2') {
materialForm.value.taxRate = 0;
} else {
form.value.contractTerritorialCountry = undefined;
}
},
{ immediate: true }
);
watch(
() => form.value.settlementCurrency,
(newVal) => {
if (newVal === 'CNY') {
form.value.rmbExchangeRate = 1 as any;
}
},
{ immediate: true }
);
//
const generateContractCode = async () => {
if (isCodeGenerated.value) return; //
@ -1292,14 +1412,16 @@ const submitOss = () => {
// contractId
const handleAddMaterial = () => {
resetMaterialForm();
editingMaterialIndex.value = null;
materialForm.value.contractId = form.value.contractId;
materialDialog.visible = true;
materialDialog.title = '新增合同物料';
};
//
const handleEditMaterial = (row: ContractMaterialVO) => {
const handleEditMaterial = (row: ContractMaterialVO, rowIndex: number) => {
resetMaterialForm();
editingMaterialIndex.value = rowIndex;
materialForm.value = { ...row };
materialDialog.visible = true;
materialDialog.title = '编辑合同物料';
@ -1333,11 +1455,14 @@ const handleDeleteMaterial = async (row: ContractMaterialVO) => {
const resetMaterialForm = () => {
materialForm.value = { ...initMaterialFormData };
materialFormRef.value?.resetFields();
// =2 0
materialForm.value.taxRate = form.value.contractTerritorialFlag === '2' ? 0 : 13;
};
//
const cancelMaterial = () => {
resetMaterialForm();
editingMaterialIndex.value = null;
materialDialog.visible = false;
};
@ -1490,7 +1615,11 @@ const submitMaterialForm = () => {
unitName: unitName
};
if (materialForm.value.contractMaterialId) {
const editIndex = editingMaterialIndex.value;
if (editIndex !== null && editIndex >= 0 && editIndex < (form.value as any).contractMaterialList.length) {
// ID
(form.value as any).contractMaterialList[editIndex] = materialData;
} else if (materialForm.value.contractMaterialId) {
//
const index = (form.value as any).contractMaterialList.findIndex(
(item: any) => item.contractMaterialId === materialForm.value.contractMaterialId
@ -1511,6 +1640,7 @@ const submitMaterialForm = () => {
calculateTotalPrice();
proxy?.$modal.msgSuccess('操作成功');
editingMaterialIndex.value = null;
materialDialog.visible = false;
}
});

@ -195,6 +195,22 @@
<span>{{ parseTime(scope.row.frameworkValidPeriod, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="合同属地标识" align="center" prop="contractTerritorialFlag" width="120" v-if="columns[44].visible">
<template #default="scope">
<dict-tag :options="contract_territorial_flag" :value="scope.row.contractTerritorialFlag" />
</template>
</el-table-column>
<el-table-column label="合同属地国家/地区" align="center" prop="contractTerritorialCountry" width="160" v-if="columns[45].visible">
<template #default="scope">
<dict-tag :options="country_region" :value="scope.row.contractTerritorialCountry" />
</template>
</el-table-column>
<el-table-column label="结算币种" align="center" prop="settlementCurrency" width="110" v-if="columns[46].visible">
<template #default="scope">
<dict-tag :options="currency_type" :value="scope.row.settlementCurrency" />
</template>
</el-table-column>
<el-table-column label="对人民币汇率" align="center" prop="rmbExchangeRate" width="120" v-if="columns[47].visible" />
<el-table-column label="备注" align="center" prop="remark" v-if="columns[24].visible" />
<el-table-column label="激活标识" align="center" prop="activeFlag" v-if="columns[25].visible">
<template #default="scope">
@ -360,7 +376,7 @@ import { CodeRuleEnum } from '@/enums/OAEnum';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute();
const router = useRouter();
const { contract_category, business_direction, active_flag, contract_flag, contract_type, contract_status, contract_template_flag } = toRefs<any>(
const { contract_category, business_direction, active_flag, contract_flag, contract_type, contract_status, contract_template_flag, contract_territorial_flag, country_region, currency_type } = toRefs<any>(
proxy?.useDict(
'contract_category',
'business_direction',
@ -368,7 +384,10 @@ const { contract_category, business_direction, active_flag, contract_flag, contr
'contract_flag',
'contract_type',
'contract_status',
'contract_template_flag'
'contract_template_flag',
'contract_territorial_flag',
'country_region',
'currency_type'
)
);
@ -429,7 +448,11 @@ const columns = ref<FieldOption[]>([
{ key: 40, label: `合同模板标识`, visible: true },
{ key: 41, label: `软控合同额(元)`, visible: true },
{ key: 42, label: `关联框架合同`, visible: true },
{ key: 43, label: `框架合同有效期`, visible: false }
{ key: 43, label: `框架合同有效期`, visible: false },
{ key: 44, label: `合同属地标识`, visible: true },
{ key: 45, label: `合同属地国家/地区`, visible: true },
{ key: 46, label: `结算币种`, visible: true },
{ key: 47, label: `对人民币汇率`, visible: true }
]);
const data = reactive<{ queryParams: ContractInfoQuery }>({
@ -445,6 +468,10 @@ const data = reactive<{ queryParams: ContractInfoQuery }>({
businessDirection: undefined,
contractDeptId: undefined,
contractDate: undefined,
contractTerritorialFlag: undefined,
contractTerritorialCountry: undefined,
settlementCurrency: undefined,
rmbExchangeRate: undefined,
totalPrice: undefined,
oneCustomerId: undefined,
oneCustomerName: undefined,

@ -181,6 +181,20 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.contractTerritorialFlag === '2'">
<el-form-item label="对人民币汇率" prop="rmbExchangeRate">
<el-input-number
v-model="form.rmbExchangeRate"
:min="0"
:precision="4"
:step="0.0001"
controls-position="right"
placeholder="请输入对人民币汇率"
style="width: 100%"
:disabled="isFormDisabled"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合同总价" prop="amount">
<el-input v-model="form.amount" placeholder="请输入合同总价" :disabled="true">
@ -873,6 +887,9 @@ type ProjectInfoFormEx = ProjectInfoForm & {
contractName?: string;
customerContractCode?: string;
finalCustomerId?: string | number;
effectiveCustomerOrderFlag?: string;
contractTerritorialFlag?: string;
rmbExchangeRate?: number;
planStageList?: ErpProjectPlanStageForm[];
projectContractsList?: any[];
};
@ -902,6 +919,8 @@ const initFormData: ProjectInfoFormEx = {
contractName: undefined,
customerContractCode: undefined,
finalCustomerId: undefined,
contractTerritorialFlag: undefined,
rmbExchangeRate: undefined,
remark: undefined,
ossId: undefined,
activeFlag: '1',
@ -919,6 +938,18 @@ const data = reactive<{ form: ProjectInfoFormEx; rules: any }>({
projectCategory: [{ required: true, message: '订单类别不能为空', trigger: 'change' }],
orderType: [{ required: true, message: '订单类型不能为空', trigger: 'change' }],
customerContractCode: [{ required: true, message: '客户合同编号不能为空', trigger: 'blur' }],
rmbExchangeRate: [
{
validator: (_rule: any, value: any, callback: (err?: Error) => void) => {
if (form.value.contractTerritorialFlag === '2' && (value === undefined || value === null || value === '')) {
callback(new Error('合同属地标识为“其他”时,对人民币汇率不能为空'));
return;
}
callback();
},
trigger: 'blur'
}
],
peopleId: [{ required: true, message: '抄送人员不能为空', trigger: 'change' }],
ossId: [{ required: true, message: '请上传终版合同', trigger: 'change' }]
}
@ -1073,6 +1104,17 @@ const getDefaultRepaymentDate = (paymentMethod?: Record<string, any>): string =>
return formatDateToYmd(target);
};
/** 回填合同扩展字段:属地标识、对人民币汇率 */
const fillContractExtraFields = (contractData: any) => {
form.value.effectiveCustomerOrderFlag = contractData?.effectiveCustomerOrderFlag;
form.value.contractTerritorialFlag = contractData?.contractTerritorialFlag;
form.value.rmbExchangeRate = contractData?.rmbExchangeRate;
//
if (contractData?.effectiveCustomerOrderFlag === '1' && contractData?.ossId) {
form.value.ossId = contractData.ossId;
}
};
/** 根据路由 contractId 加载合同信息并回填表单;有项目则加载主项目+阶段+关联项目,无则从合同带出 */
const loadContractInfo = async () => {
isFromContentChange.value = false;
@ -1105,6 +1147,7 @@ const loadContractInfo = async () => {
form.value.contractName = contractData.contractName;
form.value.customerContractCode = contractData.customerContractCode;
form.value.finalCustomerId = contractData.finalCustomerId;
fillContractExtraFields(contractData);
form.value.amount = contractData.totalPrice;
// ID
@ -1187,6 +1230,12 @@ onMounted(async () => {
if (isEditMode) {
const res = await getProjectInfo(id);
Object.assign(form.value, res.data);
if (form.value.contractId) {
const contractRes = await getContractInfo(form.value.contractId as string | number);
if (contractRes?.data) {
fillContractExtraFields(contractRes.data);
}
}
if (form.value.peopleId && typeof form.value.peopleId === 'string') {
form.value.peopleId = (form.value.peopleId as string).split(',').map((id) => String(id.trim())) as any;
}

@ -55,6 +55,21 @@
<el-table-column label="海威合同归档编号" prop="externalContractCode" width="150" align="center" show-overflow-tooltip />
<el-table-column label="客户合同编号" prop="customerContractCode" width="150" align="center" show-overflow-tooltip />
<el-table-column label="签订时间" prop="contractDate" width="110" align="center" show-overflow-tooltip />
<el-table-column label="合同属地标识" prop="contractTerritorialFlag" width="120" align="center">
<template #default="scope">
<dict-tag :options="contract_territorial_flag" :value="scope.row.contractTerritorialFlag" />
</template>
</el-table-column>
<el-table-column label="国家/地区" prop="contractTerritorialCountry" width="100" align="center" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="country_region" :value="scope.row.contractTerritorialCountry" />
</template>
</el-table-column>
<el-table-column label="结算币种" prop="settlementCurrency" width="110" align="center">
<template #default="scope">
<dict-tag :options="currency_type" :value="scope.row.settlementCurrency" />
</template>
</el-table-column>
<el-table-column label="软控SAP订单号" prop="orderContractCode" width="140" align="center" show-overflow-tooltip />
<el-table-column label="软控SAP项目号" prop="projectContractCode" width="140" align="center" show-overflow-tooltip />
<el-table-column label="客户名称" prop="customerName" width="200" align="center" show-overflow-tooltip />
@ -139,7 +154,9 @@ import { listContractLedgerReport, ContractLedgerReportQuery, ContractLedgerRepo
type ElFormInstance = InstanceType<typeof ElForm>;
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { business_direction } = toRefs<any>(proxy?.useDict('business_direction'));
const { business_direction, contract_territorial_flag, country_region, currency_type } = toRefs<any>(
proxy?.useDict('business_direction', 'contract_territorial_flag', 'country_region', 'currency_type')
);
const reportList = ref<ContractLedgerReportVO[]>([]);
const selectedRows = ref<ContractLedgerReportVO[]>([]);

Loading…
Cancel
Save