projectcost.js.svn-base 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. Ext.require([
  2. 'Gnt.plugin.TaskContextMenu',
  3. 'Sch.plugin.TreeCellEditing',
  4. 'Sch.plugin.Pan',
  5. 'Gnt.panel.Gantt',
  6. 'Gnt.column.PercentDone',
  7. 'Gnt.column.StartDate',
  8. 'Gnt.column.EndDate',
  9. 'Gnt.plugin.Printable',
  10. 'Gnt.widget.AssignmentCellEditor',
  11. 'Gnt.column.ResourceAssignment',
  12. 'Gnt.model.Assignment',
  13. 'erp.util.BaseUtil',
  14. 'Gnt.widget.Calendar'
  15. ]);
  16. Ext.onReady(function() {
  17. Ext.QuickTips.init();
  18. function getUrlParam(name){
  19. var reg=new RegExp("(^|&)"+name+"=([^&]*)(&|$)");
  20. var r=window.location.search.substr(1).match(reg);
  21. if (r!=null) return decodeURI(r[2]);
  22. return null;
  23. }
  24. var formCondition = getUrlParam('formCondition');
  25. formCondition = (formCondition == null) ? "" : formCondition.replace(/IS/g,"=");
  26. var BaseUtil=Ext.create('erp.util.BaseUtil');
  27. Ext.Ajax.request({
  28. url : basePath + "plm/gantt/getData.action",
  29. params:{
  30. condition:formCondition
  31. },
  32. async:false,
  33. method : 'get',
  34. callback : function(options,success,response){
  35. var rs = new Ext.decode(response.responseText);
  36. if(rs.exceptionInfo){
  37. showError(rs.exceptionInfo);return;
  38. }
  39. else if(rs.success){
  40. projectplandate=rs.data.prjplandata[0].prjplan_startdate;
  41. }
  42. }
  43. });
  44. Ext.define('MyTaskModel', {
  45. extend : 'Gnt.model.Task',
  46. // A field in the dataset that will be added as a CSS class to each rendered task element
  47. clsField : 'TaskType',
  48. fields : [
  49. { name : 'TaskType', type : 'string' },
  50. { name : 'TaskColor', type : 'string'},
  51. {name:'prjplanid',type:'int'},
  52. {name:'prjplanname',type:'string'},
  53. {name:'recorder',type:'string'},
  54. {name:'recorddate',type:'string'},
  55. {name:'taskcode',type:'string'},
  56. {name:'cost',type:'string'},
  57. {name:'budget',type:'string'},
  58. {name:'currency',type:'int'},
  59. {name:'id',type:'int'}
  60. ]
  61. });
  62. var printableMilestoneTpl = new Gnt.template.Milestone({
  63. prefix : 'foo',
  64. printable : true,
  65. imgSrc : 'images/milestone.png'
  66. });
  67. var taskStore = Ext.create("Gnt.data.TaskStore", {
  68. model: 'MyTaskModel',
  69. sorters : 'StartDate',
  70. proxy : {
  71. type : 'ajax',
  72. headers : { "Content-Type" : 'application/json' },
  73. extraParams :{
  74. condition:formCondition,
  75. },
  76. api: {
  77. read: basePath+'plm/gantt.action',
  78. create: basePath+'plm/ganttcreate.action',
  79. destroy: 'webservices/Tasks.asmx/Delete',
  80. update: basePath+'plm/ganttupdate.action',
  81. },
  82. writer : {
  83. type : 'json',
  84. root : 'jsonData',
  85. encode : true,
  86. nameProperty:'data',
  87. allowSingle : false
  88. },
  89. reader : {
  90. type : 'json',
  91. }
  92. }
  93. });
  94. var g = Ext.create('Gnt.panel.Gantt', {
  95. id:'gantt',
  96. height:300,
  97. layout:'anchor',
  98. //region : 'center',
  99. selModel : new Ext.selection.TreeModel({ ignoreRightMouseSelection : false, mode : 'MULTI'}),
  100. columnLines : true,
  101. loadMask: true,
  102. viewPreset: 'weekAndDayLetter',
  103. taskStore : taskStore,
  104. columns : [
  105. {
  106. xtype:'wbscolumn',
  107. header:'编号',
  108. columnWidth:3.5,
  109. },
  110. {
  111. xtype : 'treecolumn',
  112. header: '任务',
  113. sortable: true,
  114. dataIndex: 'Name',
  115. flex:1,
  116. renderer : function(v, meta, r) {
  117. if (!r.data.leaf) meta.tdCls = 'sch-gantt-parent-cell';
  118. return v;
  119. }
  120. },
  121. {
  122. header:'开始时间' ,
  123. dataIndex:'StartDate',
  124. renderer:function(val,meta,record){
  125. return Ext.util.Format.date(val,'Y-m-d');
  126. }
  127. },
  128. {
  129. header:'结束时间',
  130. dataIndex:'EndDate',
  131. renderer:function(val,meta,record){
  132. return Ext.util.Format.date(val,'Y-m-d');
  133. }
  134. },{
  135. header:'消费预测',
  136. dataIndex:'budget',
  137. format:'0.00',
  138. xtype:'numbercolumn',
  139. renderer:function(val,meta,record){
  140. if(val==0) return null;
  141. else{
  142. switch(record.data.currency){
  143. case 0: return '¥'+Ext.util.Format.number(val,'0,000.00') ;
  144. case 1: return '$'+Ext.util.Format.number(val,'0,000.00');
  145. }
  146. }
  147. },
  148. field:{
  149. }
  150. }, {
  151. header:'实际消费',
  152. dataIndex:'cost',
  153. xtype:'numbercolumn',
  154. renderer:function(val,meta,record){
  155. if(val==0) return null;
  156. else{
  157. switch(record.data.currency){
  158. case 0: return '¥'+Ext.util.Format.number(val,'0,000.00') ;
  159. case 1: return '$'+Ext.util.Format.number(val,'0,000.00');
  160. }
  161. }
  162. },
  163. field:{
  164. }
  165. }, {
  166. header:'币别',
  167. dataIndex:'currency',
  168. renderer:function(val, meta, record){
  169. if(val==0) return '人名币';
  170. else if(val==1) return '美元';
  171. },
  172. field:{
  173. xtype:'combo',
  174. editable:false,
  175. displayField:'display',
  176. valueField:'value',
  177. value:0,
  178. store:{
  179. fields:['display','value'],
  180. data:[{display:'人民币',value:0},
  181. {display:'美元',value:1},
  182. ]
  183. },
  184. }
  185. }, {
  186. header: '消费情况',
  187. tdCls: 'sch-column-color',
  188. renderer:function(val,meta,record){
  189. if(record.data.cost>record.data.budget){
  190. return '<div class="color-column-inner" style="background-color:red" align="center">&nbsp;</div>';
  191. }else return '<div class="color-column-inner" style="background-color:green" align="center">&nbsp;</div>';
  192. }
  193. }
  194. ],
  195. tbar : [{
  196. xtype: 'buttongroup',
  197. title: '操作区',
  198. columns: 6,
  199. items: [
  200. {
  201. iconCls : 'togglebutton',
  202. enableToggle: true,
  203. id : 'readonlybutton',
  204. text: '只读',
  205. pressed: true,
  206. handler: function () {
  207. if(em_id=='10000011'){
  208. g.setReadOnly(this.pressed);
  209. Ext.getCmp('savebutton').setDisabled(this.pressed);
  210. }else{
  211. this.pressed=true;
  212. g.setReadOnly(this.pressed);
  213. showError('对不起,你没有权限修改!');
  214. }
  215. },
  216. listeners: {
  217. beforerender: { //bind to the underlying el property on the panel
  218. fn: function(){
  219. if(em_id!='10000011'){
  220. this.enableToggle=false;
  221. }
  222. }
  223. }
  224. }
  225. },{
  226. iconCls : 'x-advance-print',
  227. text : '打印',
  228. handler : function() {
  229. Ext.getCmp('gantt').zoomToFit();
  230. Ext.getCmp('gantt').print();
  231. }
  232. },
  233. {
  234. iconCls : 'x-advance-save',
  235. id:'savebutton',
  236. text : '保存',
  237. listeners: {
  238. 'afterrender':function(btn,opts){
  239. if(Ext.getCmp('readonlybutton').pressed){
  240. btn.setDisabled(true);
  241. }
  242. }
  243. },
  244. handler : function(){
  245. var options={},
  246. me=g.taskStore;
  247. var toCreate = me.getNewRecords(),
  248. toUpdate = me.getUpdatedRecords(),
  249. toDestroy = me.getRemovedRecords(),
  250. needsSync = false;
  251. if (toCreate.length > 0) {
  252. var create=null;
  253. options.create = toCreate;
  254. var index = 0;
  255. var jsonData=new Array();
  256. for(var i=0;i<toCreate.length;i++){
  257. var data = toCreate[i].data;
  258. jsonData[index++] = Ext.JSON.encode(data)+'#@';
  259. }
  260. Ext.Ajax.request({
  261. url : basePath + "plm/gantt/ganttcreate.action",
  262. params:{
  263. jsonData: unescape(jsonData.toString().replace(/\\/g,"%")),
  264. },
  265. method : 'post',
  266. callback : function(options,success,response){
  267. }
  268. });
  269. }
  270. if (toUpdate.length > 0) {
  271. options.update = toUpdate;
  272. needsSync=true;
  273. var index = 0;
  274. var jsonData=new Array();
  275. for(var i=0;i<toUpdate.length;i++){
  276. var data = toUpdate[i].data;
  277. jsonData[index++] = Ext.JSON.encode(data)+'#@';
  278. }
  279. Ext.Ajax.request({
  280. url : basePath + "plm/gantt/ganttupdate.action",
  281. params:{
  282. jsonData: unescape(jsonData.toString().replace(/\\/g,"%")),
  283. },
  284. method : 'post',
  285. callback : function(options,success,response){
  286. }
  287. });
  288. }
  289. if (toDestroy.length > 0) {
  290. options.destroy = toDestroy;
  291. needsSync=true;
  292. var index = 0;
  293. var jsonData=new Array();
  294. for(var i=0;i<toDestroy.length;i++){
  295. var data = toDestroy[i].data;
  296. jsonData[index++] = Ext.JSON.encode(data)+'#@';
  297. }
  298. Ext.Ajax.request({
  299. url : basePath + "plm/gantt/ganttdelete.action",
  300. params:{
  301. jsonData: unescape(jsonData.toString().replace(/\\/g,"%")),
  302. },
  303. method : 'post',
  304. callback : function(options,success,response){
  305. }
  306. });
  307. }
  308. var gridCondition=getUrlParam("gridCondition");
  309. window.location.href = window.location.href + '?formCondition=' +
  310. formCondition + '&gridCondition=' + gridCondition;
  311. }
  312. },{
  313. text : '收缩',
  314. iconCls : 'icon-collapseall',
  315. scope : this,
  316. handler : function() {
  317. g.collapseAll();
  318. }
  319. },
  320. {
  321. text : '展开',
  322. iconCls : 'icon-expandall',
  323. scope : this,
  324. loader:{
  325. loadMask:true,
  326. },
  327. handler : function() {
  328. var loadMask= g.setLoading("正在展开",true);
  329. g.expandAll(loadMask.hide());
  330. // g.expandAll();
  331. }
  332. }, {
  333. xtype : 'textfield',
  334. emptyText : '搜索...',
  335. scope : this,
  336. width:150,
  337. //height:20,
  338. padding: '0 0 -20 0',
  339. enableKeyEvents : true,
  340. listeners : {
  341. keyup : {
  342. fn : function(field, e) {
  343. var value = field.getValue();
  344. if (value) {
  345. g.taskStore.filter('Name', field.getValue(), true, false);
  346. } else {
  347. g.taskStore.clearFilter();
  348. }
  349. },
  350. scope : this
  351. },
  352. specialkey : {
  353. fn : function(field, e) {
  354. if (e.getKey() === e.ESC) {
  355. field.reset();
  356. }
  357. g.taskStore.clearFilter();
  358. },
  359. scope : this
  360. }
  361. }
  362. }
  363. ]}
  364. ],
  365. lockedGridConfig : {
  366. //layout:'column',
  367. //region:'center',
  368. anchor:'100% 100%',
  369. title : '任务表',
  370. useArrows: true,
  371. rootVisible: false,
  372. autoScroll:true
  373. },
  374. schedulerConfig : {
  375. //hidden:true,
  376. height: '0',
  377. collapsible : true,
  378. title : '计划表'
  379. },
  380. leftLabelField : {
  381. dataIndex : 'Name',
  382. editor : { xtype : 'textfield' }
  383. },
  384. eventRenderer: function(task){
  385. return {
  386. style : 'background-color: #'+task.data.TaskColor
  387. };
  388. },
  389. _fullScreenFn : (function() {
  390. var docElm = document.documentElement;
  391. if (docElm.requestFullscreen) {
  392. return "requestFullscreen";
  393. }
  394. else if (docElm.mozRequestFullScreen) {
  395. return "mozRequestFullScreen";
  396. }
  397. else if (docElm.webkitRequestFullScreen) {
  398. return "webkitRequestFullScreen";
  399. }
  400. })(),
  401. plugins:[
  402. Ext.create("Gnt.plugin.TaskContextMenu"),
  403. Ext.create("Sch.plugin.Pan"),
  404. Ext.create('Sch.plugin.TreeCellEditing', {
  405. clicksToEdit: 1 ,
  406. listeners : {
  407. beforeedit : function() { return !Ext.getCmp('readonlybutton').pressed;
  408. }
  409. }}),
  410. new Gnt.plugin.Printable({
  411. printRenderer : function(task, tplData) {
  412. if (task.isMilestone()) {
  413. return;
  414. } else if (task.isLeaf()) {
  415. var availableWidth = tplData.width - 4,
  416. progressWidth = Math.floor(availableWidth*task.get('PercentDone')/100);
  417. return {
  418. // Style borders to act as background/progressbar
  419. progressBarStyle : Ext.String.format('width:{2}px;border-left:{0}px solid #7971E2;border-right:{1}px solid #E5ECF5;', progressWidth, availableWidth - progressWidth, availableWidth)
  420. };
  421. } else {
  422. var availableWidth = tplData.width - 2,
  423. progressWidth = Math.floor(availableWidth*task.get('PercentDone')/100);
  424. return {
  425. // Style borders to act as background/progressbar
  426. progressBarStyle : Ext.String.format('width:{2}px;border-left:{0}px solid #FFF3A5;border-right:{1}px solid #FFBC00;', progressWidth, availableWidth - progressWidth, availableWidth)
  427. };
  428. }
  429. },
  430. beforePrint : function(sched) {
  431. var v = sched.getSchedulingView();
  432. this.oldRenderer = v.eventRenderer;
  433. this.oldMilestoneTemplate = v.milestoneTemplate;
  434. v.milestoneTemplate = printableMilestoneTpl;
  435. v.eventRenderer = this.printRenderer;
  436. },
  437. afterPrint : function(sched) {
  438. var v = sched.getSchedulingView();
  439. v.eventRenderer = this.oldRenderer;
  440. v.milestoneTemplate = this.oldMilestoneTemplate;
  441. }
  442. })
  443. ],
  444. tooltipTpl : new Ext.XTemplate(
  445. '<h4 class="tipHeader">{Name}</h4>',
  446. '<table class="taskTip">',
  447. '<tr><td>开始:</td> <td align="right">{[Ext.Date.format(values.StartDate, "y-m-d")]}</td></tr>',
  448. '<tr><td>结束:</td> <td align="right">{[Ext.Date.format(values.EndDate, "y-m-d")]}</td></tr>',
  449. '<tr><td>进度:</td><td align="right">{PercentDone}%</td></tr>',
  450. '</table>'
  451. ).compile(),
  452. applyPercentDone : function(value) {
  453. this.getSelectionModel().selected.each(function(task) { task.setPercentDone(value); });
  454. },
  455. showFullScreen : function() {
  456. this.el.down('.x-panel-body').dom[this._fullScreenFn]();
  457. },
  458. openTab : function (panel,id){
  459. var o = (typeof panel == "string" ? panel : id || panel.id);
  460. var main = parent.Ext.getCmp("content-panel");
  461. var tab = main.getComponent(o);
  462. if (tab) {
  463. main.setActiveTab(tab);
  464. } else if(typeof panel!="string"){
  465. panel.id = o;
  466. var p = main.add(panel);
  467. main.setActiveTab(p);
  468. }
  469. } ,
  470. // Experimental, not X-browser
  471. _fullScreenFn : (function() {
  472. var docElm = document.documentElement;
  473. if (docElm.requestFullscreen) {
  474. return "requestFullscreen";
  475. }
  476. else if (docElm.mozRequestFullScreen) {
  477. return "mozRequestFullScreen";
  478. }
  479. else if (docElm.webkitRequestFullScreen) {
  480. return "webkitRequestFullScreen";
  481. }
  482. })()
  483. });
  484. var vp = Ext.create("Ext.Viewport", {
  485. id:'viewport',
  486. layout : 'fit',
  487. items : [
  488. /** {
  489. region : 'north',
  490. contentEl : 'north',
  491. bodyStyle : 'padding:0px'
  492. },**/
  493. g
  494. ]
  495. });
  496. });