SugarCRM 主表EditView.php 中添加子表明细Items 并一同保存

1.在主表模块中创建子表字段标签

/wwws/language/zh_cn.lang.php

'LBL_ConsignmentItem'=>'提运单明细',

'LBL_ADDROW'=>'新增明细',

'LBL_REMOVEROW'=>'删除',

'LBL_SequenceNumeric' => '托运货物序号',

'LBL_MarksNumbers' => '唛头',

'LBL_CargoDescription' => '货物简要描述',

'LBL_Content' => '备注',

2.创建Item模板

/wwws/EditView.html

</table>//在此语句后添写下面代码

<!-- BEGIN: open_source -->

<!-- END: open_source -->

<!-- END: main -->

<!-- BEGIN: Item -->

<div ></TD>

<TD class="dataField" ><INPUT class="button" /> </TD>

</TR>

<!-- END: items -->

</table>

</form>

{JAVASCRIPT}

<!-- END: Item -->

3.向模板赋值

/wwws/EditView.php

//Add Custom Fields

require_once('modules/DynamicFields/templates/Files/EditView.php');//在此语句后添写下面代码

//contract items

require_once('modules/Contracts/ContractItem.php');

$itemObj = new ContractItem();

$items = $itemObj->getAllByContractId($focus->id);

if(empty($focus->id) || empty($items))

{

$xtpl->assign("ITEM_IDX", 1);

$xtpl->assign("ITEM_SequenceNumeric",'1');

$xtpl->assign("ITEM_MarksNumbers",'');

$xtpl->assign("ITEM_CargoDescription",'');

$xtpl->assign("ITEM_Content",'');

$xtpl->assign("ITEM_ID",'');

$xtpl->parse("main.item");

}

else

{

$idx = 1;

foreach($items as $item)

{

$xtpl->assign("ITEM_IDX", $idx++);

$xtpl->assign("ITEM_SequenceNumeric",$item->SequenceNumeric);

$xtpl->assign("ITEM_MarksNumbers",$item->MarksNumbers);

$xtpl->assign("ITEM_CargoDescription",$item->CargoDescription);

$xtpl->assign("ITEM_PRODUCT_NUM",$item->product_num);

$xtpl->assign("ITEM_Content",$item->Content);

$xtpl->assign("ITEM_ID",$item->id);

$xtpl->parse("main.item");

}

}

//~~~ end contract items;

//下面的代码是控制输出,需要调整

$xtpl->parse("main.open_source");

$xtpl->parse("main");

$xtpl->out("main");//注意:main 中 没有 </from>标签 , 它在Item标签中所以下面代码必须写

echo "\n<p>\n";//输出明细的标题

echo get_module_title($mod_strings['LBL_ConsignmentItem'], $mod_strings['LBL_ConsignmentItem'].": ".$focus->name, true);

echo "\n</p>\n";

$xtpl->parse("Item.items"); //赋明细列表 <!-- BEGIN: items --> 与 <!-- END: items --> 之间

$xtpl->parse("Item"); //赋 <!-- BEGIN: Item --> 与 <!-- END: Item --> 之间

$xtpl->out("Item"); //输出 <!-- BEGIN: Item --> 与 <!-- END: Item --> 之间

4.调用javascript脚本

/wwws/EditView.html

//在文件开始部分中调用javascript的地方添写下面代码

<script type="text/javascript" src="modules/wwws/ConsignmentItem.js"></script>

<script>

lableMap =

{

'btn_del':'{MOD.LBL_REMOVEROW}'

};

</script>

5.创建javascript脚本 ,用于Item中创建新行和删除行的javascript

在模块路径下创建名为 ConsignmentItem.js 的js文件,文件应为明细item模块的名称

文件中添加下面代码

function addRow(tbId, lableMap)

{

var tbl = document.getElementById(tbId);

var count = tbl.rows.length;

var row = tbl.insertRow(count);

var cell0 = row.insertCell(row.cells.length);

cell0.innerHTML = '<input type=text size=7 value="1" name=SequenceNumeric_'+count+' +count+'>';

var cell1 = row.insertCell(row.cells.length);

cell1.innerHTML = '<input type=text size=7 value="" name=MarksNumbers_'+count+' +count+'>';

var cell2 = row.insertCell(row.cells.length);

cell2.innerHTML = '<input type=text size=7 value="0" name=CargoDescription_'+count+' +count+'>';

var cell3 = row.insertCell(row.cells.length);

cell3.innerHTML = '<input type=text size=7 value="" name=Content_'+count+' +count+'>';

var cell4 = row.insertCell(row.cells.length);

cell4.innerHTML = '<INPUT class="button" />';

// var cell7 = row.insertCell(row.cells.length);

// cell7.innserHTML = '';

}

function delRow(tbId, idx)

{

var tbl = document.getElementById(tbId);

var row = tbl.rows[idx];

row.style.display = 'none';

var delFlag = document.getElementById("rowIndexId_"+idx);

delFlag.value = 1;

//calculate();

}

6.保存

原理: save.php 控制保存的走向

SaveFormBase.php 执行保存的控制主文件(手动创建)

bw_ConsignmentItem.php 保存子表的所用文件(手动创建)

bw_Consignment.php 保存主表的所用文件(不用修改)

(1)修改 save.php

\modules\bw_Consignments\Save.php

将原有的所有代码注释掉

加入下面代码

require_once('modules/bw_Consignments/SaveFormBase.php');//引入 执行保存的控制主文件

$contractForm = new SaveFormBase();

$contractForm->handleSave('', true, false);

(2)创建 SaveFormBase.php

\modules\bw_Consignments\SaveFormBase.php \\在主表模块

加入下面代码

<?php

if(empty($GLOBALS['sugarEntry'])) die('Not A Valid Entry Point');

require_once('include/JSON.php');

class SaveFormBase{

function checkForDuplicates($prefix){

require_once('include/formbase.php');

require_once('modules/bw_Consignments/bw_Consignment.php');

$focus = new bw_Consignment();

$query = '';

$baseQuery = 'select id, Consignment_number from Consignments where deleted!=1 and (';

if(isset($_POST[$prefix.'bw_consignment_number']) && !empty($_POST[$prefix.'bw_consignment_number'])) {

$query = $baseQuery ." bw_consignment_number like '%".$_POST[$prefix.'bw_consignment_number']."%'";

$query .= getLikeForEachWord('bw_consignment_number', $_POST[$prefix.'bw_consignment_number']);

}

if(!empty($query)){

$rows = array();

require_once('include/database/PearDatabase.php');

$db = & PearDatabase::getInstance();

$result = $db->query($query.')');

if($db->getRowCount($result) == 0) {

return null;

}

for($i = 0; $i < $db->getRowCount($result); $i++) {

$rows[$i] = $db->fetchByAssoc($result, $i);

}

return $rows;

}

return null;

}

function handleSave($prefix, $redirect=true, $useRequired=false)

{

global $current_user;

require_once('modules/bw_Consignments/bw_Consignment.php');

require_once('modules/bw_Consignments/bw_ConsignmentItem.php');

require_once('log4php/LoggerManager.php');

require_once('include/formbase.php');

$focus = new bw_Consignment();

if($useRequired && !checkRequired($prefix, array_keys($focus->required_fields))) {

return null;

}

$focus = populateFromPost($prefix, $focus);

if( !ACLController::checkAccess($focus->module_dir, 'edit', $focus->isOwner($current_user->id))){

ACLController::displayNoAccess(true);

}

$check_notify = FALSE;

if (isset($GLOBALS['check_notify'])) {

$check_notify = $GLOBALS['check_notify'];

}

if (empty($_POST['record']) && empty($_POST['dup_checked'])) {

$duplicates = $this->checkForDuplicates($prefix);

if(isset($duplicates)){

$duplicateMsg = '';

foreach ($duplicates as $duplicate)

{

$duplicateMsg .= "<a href='index.php?module=" . $focus->module_dir . "&action=DetailView&record=". $duplicate['id']. "'>". $duplicate['bw_consignment_number']. "</a><br>\n";

}

die("Please check this duplicate record first.<br>\n". $duplicateMsg);

}

}

$return_id = $focus->save($check_notify);

$ci = new bw_ConsignmentItem();

$all_items = $ci->getAllById($return_id);//通过主表的id 获取此id在子表中的数据列表

$updated = array();

$keys = array_keys($_POST);//$_POST 中是主表的内容 及 子表的内容 提交的所有数据

$sum = 0;

for($index = 1; ; $index++) //子表数据 遍历一行赋赋值

{

if(!isset($_POST["SequenceNumeric_".$index])) //for循环出口

break;

$Message;//$_POST[""];

$ConsignmentID=$return_id;//主表保存后的id

$SequenceNumeric = $_POST["SequenceNumeric_".$index];

$MarksNumbers = $_POST["MarksNumbers_".$index];

$CargoDescription = $_POST["CargoDescription_".$index];

$Content = $_POST["Content_".$index];

// if($quantity <= 0 || !isset($product_id) || empty($product_id))// 条件判断

// continue;

$item_id = $_POST["item_id_".$index];

$Item = new bw_ConsignmentItem();

$deleted = $_POST['rowIndexId_'.$index];

if($deleted == 0)

{

if(!empty($item_id))

{

$Item->id = $item_id;

array_push($updated, $item_id); //if the id is empty, create one, otherwise, update it.

}

$Item->MessageID = $MessageID;

$Item->ConsignmentID = $ConsignmentID;//主表的id

$Item->SequenceNumeric = $SequenceNumeric;

$Item->MarksNumbers = $MarksNumbers;

$Item->CargoDescription = $CargoDescription;

$Item->Content = $Content;

$Item->date_entered = date("Y-m-d H:i:s");

$Item->date_modified = date("Y-m-d H:i:s");

$Item->save();

}

}

//delete some items.

foreach($all_items as $item)

{

$ci_id = $item->id;

if( !in_array($ci_id, $updated) )

$item->mark_deleted($ci_id);

}

//~~ end saving contract items.

if(!empty($_POST['duplicate_parent_id'])) {

clone_relationship($focus->db, array('bw_consignments_documents'), 'bw_consignment_id', $_POST['duplicate_parent_id'], $focus->id);

}

$return_id = $focus->id;

$GLOBALS['log']->debug("Saved record with id of ".$return_id);

if ($redirect) {

handleRedirect($return_id,"bw_Consignments" );

} else {

return $focus;

}

}

}

?>

(3)创建 bw_ConsignmentItem.php 文件

\modules\bw_Consignments\bw_ConsignmentItem.php \\在主表模块

加入下面代码

<?php

include_once('config.php');

require_once('log4php/LoggerManager.php');

require_once('include/database/PearDatabase.php');

require_once('data/SugarBean.php');

// Contact is used to store customer information.

class bw_ConsignmentItem extends SugarBean

{

// Stored fields

var $id;

var $date_entered;

var $date_modified;

var $assigned_user_id;

var $modified_user_id;

var $created_by;

var $name;

var $description;

var $deleted;

//custom fields

var $MessageID;

var $ConsignmentID;

var $SequenceNumeric;

var $MarksNumbers;

var $CargoDescription;

var $Content;

var $table_name = 'bw_consignitems';

var $object_name = 'bw_ConsignItem';

var $module_dir = 'bw_ConsignItems';

var $new_schema = true;

var $column_fields = Array('id'

,'MessageID'

,'ConsignmentID'

,'SequenceNumeric'

,'MarksNumbers'

,'CargoDescription'

,'deleted'

,'date_entered'

,'date_modified'

,'created_by'

);

var $list_fields= array();

var $required_fields = array();

function Order()

{

parent::SugarBean();

$this->list_fields = $this->column_fields;

}

function get_xtemplate_data() {

$return_array = array();

global $current_user;

foreach($this->column_fields as $field) {

$return_array[strtoupper($field)] = $this->$field;

}

return $return_array;

}

function mark_deletedById($id) {

$return_array = $this->get_full_list("id","Consignment.$id."'");

foreach ($return_array as $value) {

$this->mark_deleted($value->id);

}

}

function fill_in_additional_list_fields() {

$this->fill_in_additional_detail_fields();

$this->single_total = $this->quantity * $this->trade_price;

}

function getAllById($id)//传入主表的保存后的id

{

$return_array = $this->get_full_list("id","Consignment.$id."'");

return $return_array;

}

}

?>