SuiteScritp 2.0开发实例 自定义工单+领料单 单据流转 打印

SuiteScritp 2.0开发实例 自定义工单+领料单 单据流转 打印

1. 业务流程


Created with Raphaël 2.2.0 开始 创建工单 是否已批准? 创建领料单 是否已批准? 打印领料单 结束 yes no yes no

2. 系统实现

2.1 自定义工单

借助SuiteBuilder

2.2 自定义领料单

借助SuiteBuilder

2.3 自定义审批工作流

借助SuiteWorkflow

2.4 SuiteScript开发


工单 领料单 领料单打印 你好!领料员xxx,我已被批准,请及时创建领料单! 创建领料单 我有哪些领料单 我的领料单号是xxx ! 你好!我已被批准,可以打印出来啦! 生成PDF 打印日志:状态、次数 批量打印. 工单 领料单 领料单打印
2.4.1 工单状态变更提醒(需求)
  • 功能设计:如果新增已批准工单,邮件、NS站内信通知领料员
  • 技术设计:创建已保存搜索,并基于它设置邮件、NS remind提醒相应领料员
2.4.2 从工单创建领料单(需求)
  • 功能设计:
    a) if 工单状态 = approved , 工单界面添加【生成领料单】按钮
    b) 点击此按钮,弹出领料单新增页面
    c) 领料单字段(来源工单、领料员、领料车间、仓库等)初始化赋值取自工单
  • 技术设计:
    a) UserEventScript beforeLoad入口点函数完成页面按钮加载(参见附:WorkOrderToMaterialApplyBs.js)
    b) 按钮函数,url 模块API resolveRecord 解析记录类型,生成新url并跳转(参见附:CreateMAOBs.js)
    c) UserEventScript beforeLoad完成页面初始化,调用record模块 API 获取工单数据
    WorkOrderToMaterialApplyBs.js
2.4.3 工单可以查询到关联领料单号(需求)
  • 功能设计:
    a) 工单添加一个子标签,下面可以查出领料单列表(头信息)
    b) 通过工单行,可以查看该行对应哪些领料单(行信息)
  • 技术设计:
    领料单创建时,需要记录来源单据(工单)的头行信息
    工单页面通过UserEventScript beforeLoad加载领料单信息。
2.4.4 领料单批准后通知打印统计员(需求)
  • 功能设计:如果新增已批准领料单,邮件、NS站内信通知领料员
  • 技术设计:创建已保存搜索,并基于它设置邮件、NS remind提醒相应领料员
2.4.5 已批准的领料单打印PDF
  • 功能设计:
    a) if 领料单审批状态 = approved, 添加 【打印领料单】 按钮
    b) 点击【打印领料单】按钮,出来PDF预览页面

  • 技术设计:
    a) UserEventScript API beforeLoad 完成页面按钮加载(参见MAOCreateFromWO.js)

// 伪代码
   if (type == VIEW && status == 'APPROVED'){
    		 	addButton('打印领料单',' print_function')
    		 }

b) 打印按钮方法调用url模块resolveScript(用此API解析Suitelet)生成,并添加参数领料单id。Suitelet将领料单数据转换成xml,再调用render模块API(xmlToPdf)转换成PDF输出。(参见BSPrintMAO.js 和 BsPrintMAOSuitelet.js)

var u = url.resolveScript({
					scriptId : 'customscript_yq_bs_printmao_suitelet',
					deploymentId : 'customdeploy_yq_bs_printmao_suitelet',
					returnExternalUrl : false			
				});

WorkOrderToMaterialApplyBs.js

/**
 * @NApiVersion 2.x
 * @NScriptType UserEventScript
 * @NModuleScope SameAccount
 * @author YQ12681
 */
Function Description//
// #1 工单页面加载前
// #1.1 如果是新建模式(type=CREATE), 什么也不做
// #1.2 如果是查看模式(type=VIEW),判断工单状态status
//		if status = 'APPROVED', 页面添加'生成领料单'按钮
//
define([], function() {
	function beforeLoad(context) {
		// context. newRecord,type,form,request		
		if (context.type === context.UserEventType.CREATE)
			;
		/*context.newRecord.setValue({
			fieldId : 'custrecord_yq_workorder_status_bs',
			value : 1
		});

		* CREATE type下不能用getText,需要先setValue或setText
		* 否则会报错: SuiteScript 2.0 Error > SSS_INVALID_API_USAGE error
		* 
		* Cause: In Standard Mode, SSS_INVALID_API_USAGE error appears when a
		* user event scripts instantiates records by using the newRecord object
		* provided by the script context in the following scenaros: -- When the
		* script executes on a record that is being created, and the script
		* attempts to use Record.getText(options) without first using
		* Record.setText(options) for the same field. -- When the script
		* executes on an existing record or on a record being created through
		* copying, and the script uses Record.setValue(options) on a field
		* before using Record.getText(options) for the same field
		*/
		else if (context.type === context.UserEventType.VIEW) {
			var status = context.newRecord.getText({
				fieldId : 'custrecord_yq_workorder_status_bs'
			});

			// 如果工单状态已审批加载<生成领料单>按钮
			try {
				if (status === 'APPROVED') {

					context.form.clientScriptModulePath = './CreateMAOBs.js';
					context.form.addButton({
						id : 'custpage_generate_mao',
						label : '生成领料单',
						functionName : 'create_mao_url'
					});
				}
				log.debug({
					title : 'Success',
					details : '添加-生成领料单-按钮成功! status = ' + status
				});
			} catch (ex) {
				log.debug({
					title : ex.name,
					details : ex.message
				});
			}
		}
	}

	return {
		beforeLoad : beforeLoad
	};
});

CreateMAOBs.js

/**
 * @NApiVersion 2.x
 * @author YQ12681
 */
Description//
//
// 定义【生成领料单】按钮的方法
// 此方法生成并打开一个新URL
//

define([ 'N/url', 'N/currentRecord' ], function(url, currentRecord) {
	return ({
		create_mao_url : function() {
			try {
				var u = url.resolveRecord({
					recordType : 'customrecord_yq_material_apply_bansi',
					recordId : '',
					isEditMode : true
				});
				log.debug({
					title : 'Success',
					details : 'url解析成功'
				});
			} catch (e1) {
				log.debug({
					title : e1.name,
					details : e1.message
				});
			}
			try {
				var record = currentRecord.get();
				var woid = record.id;
				/*var status = record.getValue({
					fieldId : 'custrecord_yq_workorder_status_bs'
				});*/
				log.debug({
					title : 'Success',
					details : '获取记录id =' + woid //+ ' status = ' + status
				});
			} catch (e2) {
				log.debug({
					title : e2.name,
					details : e2.message
				});
			}
			try {
				//if (status == 'APPROVED')
					window.location.href = u + '&woid=' + woid;
				log.debug({
					title : 'Success',
					details : 'url创建成功'
				});
			} catch (e3) {
				log.debug({
					title : e3.name,
					details : e3.message
				});
			}
		}
	});
});

MAOCreateFromWO.js

/**
 * @NApiVersion 2.x
 * @NScriptType UserEventScript
 * @author YQ12681 Bansi
 * MAOCreateFromWO.js
 */
Function Description//
// #1 领料单页面加载前
// #1.1 如果是新建模式(type=CREATE),判断是否从工单自动创建
//		if true, 用工单数据初始化赋值领料单
//		if false, 手工填写赋值
// #1.2 如果是查看模式(type=VIEW),判断工单状态status
//		if status = 'APPROVED', 页面添加'打印领料单'按钮
//
define(
		[ 'N/record' ],
		function(record) {
			function beforeLoad(context) {
				var maoRecord = context.newRecord;
				var type = context.type;
				var form = context.form;

				if (type == context.UserEventType.CREATE) {
					try {
						var woid = context.request.parameters.woid;
						if (woid) {
							var rec = record.load({
								type : 'customrecord_yq_workorder_bs',
								id : woid
							});
							//初始化赋值master
							var warehouse = rec.getValue({
								fieldId : 'custrecord_yq_workorder_shop_bs'
							});
							var clerk = rec.getValue({
								fieldId : 'custrecord_yq_workorder_lly_bs'
							});
							var workshop = rec.getValue({
								fieldId : 'custrecord_yq_workorder_dept_bs'
							});
							maoRecord.setValue(
									'custrecord_yq_mao_header_sourcewo_bs',
									woid);
							maoRecord.setValue(
									'custrecord_yq_mao_source_workshop_bs',
									workshop);
							maoRecord.setValue(
									'custrecord_yq_material_apply_requestor',
									clerk);
							maoRecord.setValue('custrecord_yq_warehouse_bansi',
									warehouse);
							maoRecord.setValue(
									'custrecord_yq_material_apply_note_bansi',
									'创建自工单:' + rec.getText({
										fieldId : 'name'
									}));

							//初始化赋值明细行
							//sublistid为recmach+子记录中作为外键到父记录的字段ID
							var sublistIdToSet = 'recmachcustrecord_yq_material_apply_detail_h_bs';
							var sublistIdToGet = 'recmachcustrecord_yq_workorder_detail_headid_bs';
							var count = rec.getLineCount(sublistIdToGet);
							for (var i = 0; i < count; i++) {
								maoRecord
										.setSublistValue(
												sublistIdToSet,
												'custrecord1',
												i,
												rec
														.getSublistValue(
																sublistIdToGet,
																'custrecord_yq_workorder_detail_item_bs',
																i));
								maoRecord
										.setSublistValue(
												sublistIdToSet,
												'custrecord_yq_material_apply_line_qyt_bs',
												i,
												rec
														.getSublistValue(
																sublistIdToGet,
																'custrecord_yq_workorder_detail_qty_bs',
																i));
							}

						}
						log.debug({
							title : 'Success',
							details : '赋值成功:woid = ' + woid + ', warehouse = '
									+ warehouse + ', clerk = ' + clerk
									+ ', workshop = ' + workshop
									+ ', sublist = ' + rec.getSublist()
						});
					} catch (e1) {
						log.debug({
							title : e1.name,
							details : e1.message
						});
					}
				} else if (type == context.UserEventType.VIEW) {
					var status = context.newRecord.getText({
						fieldId : 'custrecord_yq_ma_status_bansi'
					});
					try {
						if (status == 'APPROVED') {
							form.clientScriptModulePath = './BsPrintMAO.js';
							form.addButton({
								id : 'custpage_print_mao',
								label : '打印领料单',
								functionName : 'bs_print_mao'
							});

							log.debug({
								title : 'Success',
								details : '添加-打印领料单-按钮成功!'
							});
						}
					} catch (ex) {
						log.debug({
							title : ex.name,
							details : ex.message
						});

					}
				}
			}

			function beforeSubmit(context) {
				if (context.type != context.UserEventType.CREATE)
					return;

			}

			return ({
				beforeLoad : beforeLoad,
				beforeSubmit : beforeSubmit
			});
		});

BSPrintMAO.js

/**
 * @NApiVersion 2.x
 * @author YQ12681
 * BSPrintMAO.js
 */
 Description///
//
// 定义【打印领料单】的方法
// 此方法解析脚本记录id和部署id, 生成一个对suitelet的调用URL
//
/
define([ 'N/url', 'N/currentRecord' ], function(url, currentRecord) {
	return ({
		bs_print_mao : function() {
			try {
				var record = currentRecord.get();
				var maoId = record.id;
				var u = url.resolveScript({
					//BsPrintMAO.js
					scriptId : 'customscript_yq_bs_printmao_suitelet',
					deploymentId : 'customdeploy_yq_bs_printmao_suitelet',
					returnExternalUrl : false
				// if true 报错:不允许您直接到此页面  https://forms.eu1.netsuite.com/app/site/hosting/scriptlet.nl
				//?script=18&deploy=1&compid=5144758_SB1&h=2882965d29273aadff92&maoid=1
				// if false 可行

				});
				u += '&maoid=' + maoId;
				log.debug({
					title : 'Success',
					details : 'url解析成功'
				});
			} catch (e1) {
				log.debug({
					title : e1.name,
					details : e1.message
				});
			}
			window.open(u);
		}
	});
});

BsPrintMAOSuitelet.js

/**
 * @NApiVersion 2.x
 * @NScriptType Suitelet
 * @author YQ12681
 * BsPrintMAOSuitelet.js
 */
 Description
//
//此Suitelet接收请求参数领料单Id(maoId)
//并输出PDF预览响应
//
//
define(
		[ 'N/record', 'N/render' ],
		function(record, render) {
			function onRequest(params) {
				//解析url参数 maoid
				var maoId = params.request.parameters.maoid;

				//加载领料申请记录
				var rec = record.load({
					type : 'customrecord_yq_material_apply_bansi',
					id : maoId
				});
				var maoNumber = rec.getText('name');

				//xml定义打印模板
				var xmlStr = '';
				xmlStr += '<?xml version="1.0"?><!DOCTYPE pdf PUBLIC "-//big.faceless.org//report" "report-1.1.dtd"><pdf><head>';
				xmlStr += '</head>';
				xmlStr += '<body padding="0.5in 0.5in 0.5in 0.5in" size="Letter">';
				xmlStr += '<table style="width: 100%; font-size: 10pt;"><tr>';
				xmlStr += '<td>' + maoNumber + '</td></tr>';
				xmlStr += '</table></body>';
				xmlStr += '</pdf>'

				//xml转成pdf文件
				var pdfFile = render.xmlToPdf({
					xmlString : xmlStr
				});

				//输出文件
				params.response.writeFile({
					file : pdfFile,
					isInline : true
				});

			}

			return {
				onRequest : onRequest
			};
		});
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值