feat_check_fill (#954)

Co-authored-by: lyx <2027667395@qq.com>
Reviewed-on: daoyoucloud/tachybase#954
Co-authored-by: hello@lv <2256334253@qq.com>
Co-committed-by: hello@lv <2256334253@qq.com>
This commit is contained in:
hello@lv 2024-05-09 20:12:59 +08:00 committed by sealday
parent 424c109b25
commit c6fdba41e6
6 changed files with 272 additions and 123 deletions

View File

@ -58,12 +58,14 @@ export const PdfIsDoubleProvider = (props) => {
export const useRecordPdfPath = () => {
const record = useRecord();
let recordId = record.id;
let recordId = record.id || record.record_id;
let stockId;
if (record.__collectionName === 'contracts' && record.__parent) {
// 查看页面中间表id
recordId = record.__parent.id;
}
if (typeof record.id === 'string') {
recordId = record.id.split('_')[1] || record.id;
if (record.__collectionName === 'record_stock') {
stockId = record.id;
}
const { isDouble } = useContext(PdfIsDoubleContext);
const { settingType } = useContext(PdfIsLoadContext);
@ -73,8 +75,8 @@ export const useRecordPdfPath = () => {
const { annotate } = useContext(AnnotateContext);
const path = useMemo(
() =>
`/records:pdf?recordId=${recordId}&isDouble=${isDouble}&settingType=${settingType}&margingTop=${margingTop}&paper=${paper}&font=${size}&annotate=${annotate}`,
[recordId, isDouble, settingType, margingTop, paper, size, annotate],
`/records:pdf?recordId=${recordId}&stockId=${stockId}&isDouble=${isDouble}&settingType=${settingType}&margingTop=${margingTop}&paper=${paper}&font=${size}&annotate=${annotate}`,
[recordId, isDouble, settingType, margingTop, paper, size, annotate, stockId],
);
return path;
};

View File

@ -195,17 +195,106 @@ export class RecordPreviewController {
@Action('pdf')
async printPreview(ctx: Context) {
// 中间表id盘点单id单双列展示人工/全部/带金额,距上边距,纸张,字体,注解
const {
params: { recordId: id, isDouble, settingType, margingTop, paper, font, annotate },
params: { recordId: id, stockId, isDouble, settingType, margingTop, paper, font, annotate },
} = ctx.action;
// #region 样式参数
let pdfTop: number;
if (Number(margingTop)) {
pdfTop = Number(margingTop);
} else {
const currentUser = await ctx.db.getRepository('users').findOne({ filter: { id: ctx.state.currentUser.id } });
pdfTop = Number(currentUser?.pdf_top_margin);
}
const isAnnotate = annotate === 'true' ? true : false;
// 查询合同订单中间表获得订单id合同id出入库信息
const intermediate = await ctx.db.getRepository('record_contract').findOne({ filter: { id } });
const recordId = intermediate.record_id;
const contractId = intermediate.contract_id;
// 订单基本数据
const baseRecord = await ctx.db.getRepository('records').findOne({
const pdfExplain = await ctx.db.getRepository('basic_configuration').find();
const double = isDouble === '0' || isDouble === '1' ? isDouble : pdfExplain[0].record_columns;
const printSetup =
settingType === '0' || settingType === '1' || settingType === '2'
? settingType
: pdfExplain[0]?.record_print_setup;
// #endregion 样式参数
// #region 查询视图前执行更新视图用来确定所有产品的相关父级id
const products_view = this.sqlLoader.sqlFiles['products_search_rule_special'];
await ctx.db.sequelize.query(products_view);
// #endregion
// 1.盘点单 只需要 leaseData
// 2.租赁/购销单 需要 leaseData、leaseFeeData、noLeaseProductFeeData、noRuleexcluded
// 3.暂存单 只需要 leaseData
let leaseData = [];
let leaseFeeData = [];
let noLeaseProductFeeData = [];
let noRuleexcluded = [];
let contracts = {};
let intermediate: any;
let baseRecord: any;
if (stockId !== 'undefined') {
// 盘点单
leaseData = await ctx.db.sequelize.query(
`
select
p.id AS products_id,
p2.id AS "parentId",
ri."comment",
p2.name AS "parentName",
p2.name || '[' || p.name || ']' AS "name",
p2.unit,
p2.convertible,
p2.conversion_unit,
p.weight AS products_weight,
p.ratio AS products_ratio,
ri.count,
2 as conversion_logic_id
from record_stock rs
join record_items ri on ri.stock_id = rs.id
join products p on p.id = ri.new_product_id
left join products p2 on p2.id = p."parentId"
where rs.id = :stockId`,
{
replacements: {
stockId,
},
type: QueryTypes.SELECT,
},
);
const record_stock = await ctx.db
.getRepository('record_stock')
.findOne({ where: { id: stockId }, appends: ['project'] });
const userID = record_stock.createdById || record_stock.updatedById || 6; // 记得将盘点用户信息补全
const user = await ctx.db.getRepository('users').findOne({ filter: { id: userID } });
baseRecord = {
number: record_stock.id, // 记得生成单号替换
date: record_stock.date,
pdfExplain: pdfExplain[0]?.out_of_storage_explain,
nickname: user.nickname,
userPhone: user.phone,
systemName: pdfExplain[0]?.name,
plate: record_stock.project.name,
};
} else {
// 租赁/购销/暂存单
// 判断是外部视图查看还是表单中间表查看
let model = 'record_contract';
let isStock = false;
if (id.split('_').length > 1) {
// 视图的情况
model = 'view_records_contracts';
}
intermediate = await ctx.db.getRepository(model).findOne({ filter: { id } }); // 中间表/出入库视图
const recordId = intermediate.record_id; // 订单id
const contractId = intermediate.contract_id; // 合同id
let intermediateId = intermediate.id; // 中间表id
if (id.split('_').length > 1) {
// 视图的情况
intermediateId = parseInt(id.split('_')[1]);
}
baseRecord = await ctx.db.getRepository('records').findOne({
filter: { id: recordId },
appends: [
'vehicles',
@ -217,44 +306,101 @@ export class RecordPreviewController {
'out_stock.contacts',
],
});
let number;
if (intermediate.number) {
// 视图查看
number = intermediate.number;
} else if (!intermediate.number && model === 'record_contract') {
const view = await ctx.db
.getRepository('view_records_contracts')
.findOne({ filter: { rc_id: intermediateId } });
number = view.number;
}
baseRecord.number = number || baseRecord.number;
// 3.拼接订单的pdf基础数据 用户信息
const userID = baseRecord.createdById || baseRecord.updatedById;
const user = await ctx.db.getRepository('users').findOne({ filter: { id: userID } });
baseRecord.nickname = user?.nickname || '';
baseRecord.userPhone = user?.phone || '';
// 拉侧面文字说明
const pdfExplain = await ctx.db.getRepository('basic_configuration').find();
// 侧面栏提示信息
baseRecord.pdfExplain = pdfExplain[0]?.out_of_storage_explain;
const products_view = this.sqlLoader.sqlFiles['products_search_rule_special'];
await ctx.db.sequelize.query(products_view);
// 租金数据
const leaseData: any = await ctx.db.sequelize.query(this.sqlLoader.sqlFiles['pdf_record_product_item'], {
replacements: {
recordId,
contractId,
baseRecord.systemName = pdfExplain[0]?.name;
isStock = intermediate.record_category === '3'; // 判断是否为暂存单
if (isStock) {
contracts['record_category'] = '3';
const company = await ctx.db.getRepository('company').findOne({
filter: {
id: intermediate.company_id,
},
type: QueryTypes.SELECT,
appends: ['projects'],
});
// 租金赔偿数据
const leaseFeeData: any = await ctx.db.sequelize.query(this.sqlLoader.sqlFiles['pdf_record_product_fee_item'], {
replacements: {
intermediateId: intermediate.id,
},
type: QueryTypes.SELECT,
});
// 无关联数据
const noLeaseProductFeeData: any = await ctx.db.sequelize.query(
this.sqlLoader.sqlFiles['pdf_record_no_porduct_fees'],
contracts['first_party'] = company;
const movement = company.projects.find((item) => item.id === baseRecord.in_stock_id) ? '1' : '-1';
contracts['movement'] = movement;
// 暂存单只需要leaseDate
leaseData = await ctx.db.sequelize.query(
`
select
p.id AS products_id,
p2.id AS "parentId",
ri."comment",
p2.name AS "parentName",
p2.name || '[' || p.name || ']' AS "name",
p2.unit,
p2.convertible,
p2.conversion_unit,
p.weight AS products_weight,
p.ratio AS products_ratio,
ri.count,
2 as conversion_logic_id
from records r
join record_items ri on ri.record_id = r.id
join products p on p.id = ri.new_product_id
left join products p2 on p2.id = p."parentId"
where r.id = :recordId`,
{
replacements: {
recordId,
contractId,
},
type: QueryTypes.SELECT,
},
);
} else {
contracts = await ctx.db.getRepository('contracts').findOne({
filter: {
id: intermediate.contract_id,
},
appends: ['first_party', 'first_party.projects', 'party_b', 'party_b.projects'],
});
contracts['movement'] = intermediate.movement;
// 租赁/购销
leaseData = await ctx.db.sequelize.query(this.sqlLoader.sqlFiles['pdf_record_product_item'], {
replacements: {
recordId,
contractId,
},
type: QueryTypes.SELECT,
});
// 租金产品赔偿
leaseFeeData = await ctx.db.sequelize.query(this.sqlLoader.sqlFiles['pdf_record_product_fee_item'], {
replacements: {
intermediateId: parseInt(intermediateId),
},
type: QueryTypes.SELECT,
});
// 无关联数据
noLeaseProductFeeData = await ctx.db.sequelize.query(this.sqlLoader.sqlFiles['pdf_record_no_porduct_fees'], {
replacements: {
recordId,
contractId,
},
type: QueryTypes.SELECT,
});
// 比如运费按照出入库量,但是录单存在排除的情况,特殊处理
const noRuleexcluded: any = await ctx.db.sequelize.query(
noRuleexcluded = await ctx.db.sequelize.query(
`
select
rfin.count ,
@ -271,32 +417,15 @@ export class RecordPreviewController {
`,
{
replacements: {
intermediateId: intermediate.id,
intermediateId: parseInt(intermediateId),
},
type: QueryTypes.SELECT,
},
);
// 合同基本数据
const contracts = await ctx.db.getRepository('contracts').findOne({
filter: {
id: intermediate.contract_id,
},
appends: ['first_party', 'first_party.projects', 'party_b', 'party_b.projects'],
});
contracts.movement = intermediate.movement;
const double = isDouble === '0' || isDouble === '1' ? isDouble : pdfExplain[0].record_columns;
const printSetup =
settingType === '0' || settingType === '1' || settingType === '2'
? settingType
: pdfExplain[0]?.record_print_setup;
if (Number(margingTop)) {
pdfTop = Number(margingTop);
} else {
const currentUser = await ctx.db.getRepository('users').findOne({ filter: { id: ctx.state.currentUser.id } });
pdfTop = Number(currentUser?.pdf_top_margin);
}
}
// #endregion
const cache = ctx.app.cacheManager.getCache('@hera/plugin-rental') as Cache;
const key = stringify({
intermediate,

View File

@ -222,8 +222,7 @@ const PreviewDocument = ({
}
const paper = options.paper;
const isDouble = Number(options.isDouble);
const explain =
detail.type_new === '1'
const explain = !detail.record_category
? `盘点单用于清算仓库盈亏盈余。`
: `如供需双方未签正式合同,本${
detail.record_category
@ -377,15 +376,18 @@ const PreviewDocument = ({
));
};
const projectPhone = detail.record_party_b.contacts?.map((item) => (item.name || '') + (item.phone || '')).join(' ');
const projectPhone = detail.record_party_b?.contacts?.map((item) => (item.name || '') + (item.phone || '')).join(' ');
const car = detail.vehicles ? detail.vehicles.map((item) => item?.number).join(' ') : '';
return (
<Document>
<Page size={paper || 'A4'} style={{ ...styles.page, marginTop: options.margingTop }}>
{' '}
{/**transform: `scale(${trans})` */}
<Text style={styles.title}>{detail.contract_first_party?.name || '异常数据,请联系相关负责人!'}</Text>
<Text style={styles.title}>
{!detail.record_category
? detail.plate
: detail.contract_first_party?.name || detail.systemName || '异常数据,请联系相关负责人!'}
</Text>
<Text style={styles.subTitle}>{detail.contract_first_party ? detail.movement : '盘点'}</Text>
<View style={styles.content}>
<View style={styles.main}>
@ -415,11 +417,12 @@ const PreviewDocument = ({
</View>
)}
{detail.record_category === '购销' && (
{(detail.record_category === '购销' || detail.record_category === '暂存') && (
<View>
<View style={styles.tableHeader}>
<Text style={styles.headerLeftLeft}>
{detail.record_party_b.company.name || ''} {detail.record_party_b.name || ''}
{detail.record_category === '暂存' ? '出库方:' : '销售单位:'}
{detail.record_party_b?.company?.name || ''} {detail.record_party_b.name || ''}
</Text>
<Text style={styles.headerMiddle}>
{detail.record_date && dayjs(detail.record_date).format('YYYY-MM-DD')}
@ -427,7 +430,10 @@ const PreviewDocument = ({
<Text style={styles.headerLeftRight}>{detail.record_number}</Text>
</View>
<View style={styles.tableHeader}>
<Text style={styles.headerLeftLeft}>{detail.record_party_a.name || ''}</Text>
<Text style={styles.headerLeftLeft}>
{detail.record_category === '暂存' ? '入库方:' : '采购单位:'}
{detail.record_party_a.name || ''}
</Text>
<Text style={styles.headerMiddle}>{car}</Text>
<Text style={styles.headerLeftRight}>{detail.record_origin}</Text>
</View>
@ -436,7 +442,7 @@ const PreviewDocument = ({
{!detail.record_category && (
<View>
<View style={styles.tableHeader}>
<Text style={styles.headerLeftLeft}>{detail.record_party_a.name || ''}</Text>
<Text style={styles.headerLeftLeft}>{detail.plate || ''}</Text>
<Text style={styles.headerMiddle}>
{detail.record_date && dayjs(detail.record_date).format('YYYY-MM-DD')}
</Text>

View File

@ -36,28 +36,30 @@ export class RecordPdfService {
};
return data[movement];
};
const record_category = (category) => {
const data = {
'1': '购销',
'2': '租赁',
'3': '暂存',
// 非盘点单的情况就是暂存单
};
return data[category];
};
const needRecord = {
record_type: baseRecord.type_new,
record_number: baseRecord.number,
record_date: baseRecord.date,
record_origin: baseRecord.origin,
record_party_b: movement(contracts.movement) === '出库' ? baseRecord.in_stock : baseRecord.out_stock, // 还需要判断第三个合同的情况,确定一下出库入是否合同公司有关
record_party_a: movement(contracts.movement) === '入库' ? baseRecord.in_stock : baseRecord.out_stock,
vehicles: baseRecord.vehicles,
record_origin: baseRecord?.origin,
record_party_b: movement(contracts.movement) === '出库' ? baseRecord?.in_stock : baseRecord?.out_stock, // 还需要判断第三个合同的情况,确定一下出库入是否合同公司有关
record_party_a: movement(contracts.movement) === '入库' ? baseRecord?.in_stock : baseRecord?.out_stock,
vehicles: baseRecord?.vehicles,
record_category: record_category(contracts.record_category),
contract_first_party: contracts.first_party, //公司信息,甲方,我们
movement: movement(contracts.movement),
pdfExplain: baseRecord.pdfExplain,
nickname: baseRecord.nickname,
userPhone: baseRecord.userPhone,
systemName: baseRecord.systemName,
plate: baseRecord.plate,
};
// !租金数据
const leasePorducts = leaseData.map((leas) => {
@ -126,7 +128,7 @@ export class RecordPdfService {
total = count * fee.fee_weight;
conversion_unit = 'KG';
} else if (fee.conversion_logic_id > 4) {
const ProductWeightRule = leaseData.findOne((leas) => leas.products_id === fee.products_id);
const ProductWeightRule = leaseData.find((leas) => leas.products_id === fee.products_id);
if (ProductWeightRule.wr_logic_id === ConversionLogics.Keep) {
total = count * ProductWeightRule.wr_weight;
} else if (ProductWeightRule.wr_logic_id === ConversionLogics.Product) {

View File

@ -19,8 +19,7 @@ FROM
records r
JOIN contracts c ON c.id = :contractId
LEFT JOIN contract_items ci ON c.id = ci.contract_id
AND ci.start_date <= r."date"
AND ci.end_date >= r."date"
AND ci.date_range @> r."date"
LEFT JOIN contract_plans cp ON cp.id = ci.contract_plan_id
JOIN contract_plan_lease_items cpli ON (
cpli.contract_plan_id = cp.id

View File

@ -12,7 +12,16 @@ SELECT
p.id AS project_id,
rc.has_receipt,
rc.has_stub,
c.record_category
c.record_category,
(
CASE
WHEN c1.abbreviation IS NOT NULL THEN c1.abbreviation::TEXT
ELSE c1.id::TEXT
END || '-' || CASE
WHEN c2.abbreviation IS NOT NULL THEN c2.abbreviation::TEXT
ELSE c2.id::TEXT
END || '-' || r.number
)::CHARACTER VARYING AS number
FROM
records r
JOIN record_contract rc ON rc.record_id = r.id
@ -24,6 +33,7 @@ FROM
ELSE r.in_stock_id
END
)
JOIN company c2 ON c2.id = c.party_b_id
WHERE
r.direct_record_id IS NULL
UNION ALL
@ -44,7 +54,8 @@ SELECT
p3.id AS project_id,
rc.has_receipt,
rc.has_stub,
'3' AS record_category
'3' AS record_category,
r.number::VARCHAR AS number
FROM
records r
LEFT JOIN record_contract rc ON rc.record_id = r.id