1 //<script type="text/javascript">
3 // Auto generated file - created by app.Builder.js- do not edit directly (at present!)
5 Pman.Tab.XtupleSalesPlanning = new Roo.XComponent({
6 part : ["Xtuple","SalesPlanning"],
7 order : '600-Pman.Tab.XtupleSalesPlanning',
9 parent : 'Pman.Tab.XtupleSales',
10 name : "Pman.Tab.XtupleSalesPlanning",
18 xtype: 'NestedLayoutPanel',
21 activate : function (_self)
23 // Roo.log(Pman.hasPerm('Xtuple.SalesPlanner', 'S'));
24 // Roo.log(Pman.Login.authUser);
30 title : "Sales Planning",
32 xtype: 'BorderLayout',
36 xtype: 'NestedLayoutPanel',
39 activate : function (_self)
41 _self.layout.getRegion('center').showPanel(0);
49 xtype: 'BorderLayout',
56 activate : function() {
60 // _this.grid.footer.onClick('first');
77 //_this.dialog = Pman.Dialog.FILL_IN
78 // if (_this.panel.active) {
79 // this.footer.onClick('first');
83 autoExpandColumn : 'item_descrip1',
86 xtype: 'RowSelectionModel',
89 afterselectionchange : function (_self)
92 _this.sgrid.footer.onClick('first');
102 beforeload : function (_self, o)
104 o.params = o.params || {};
106 var s = _this.wgrid.getSelectionModel().getSelected();
108 _this.grid.ds.removeAll();
111 _this.sgrid.ds.removeAll();
113 o.params._with_year_total = 1;
115 o.params._charass_brand_value = _this.brandSel.getValue();
116 o.params._charass_group_value = _this.groupSel.getValue();
118 o.params._with_itemsrc_active = 1;
119 o.params._in_cust_id = s.data.cust_id;
121 var date = new Date();
122 var year = date.getFullYear(); // four digits
123 var month = date.getMonth(); // 0-11
125 var cm = _this.grid.getColumnModel();
126 function cid(str) {
\r
127 return cm.getIndexByDataIndex(str);
\r
130 cm.setColumnHeader(cid('total_before_last_year'),'Total ' + (year - 2));
131 cm.setColumnHeader(cid('total_last_year'),'Total ' + (year - 1));
132 cm.setColumnHeader(cid('forecast_this_year'),'Forecast ' + year);
133 cm.setColumnHeader(cid('total_this_year'),'Total ' + year);
136 cm.setColumnHeader(cid('forecast_next_year'),'Total ' + (year + 1));
137 cm.setHidden(cid('forecast_next_year'),false);
139 // it make the grid slow, change it later!
140 if(s.data.cust_name == 'All Companies'){
141 cm.setHidden(cid('forecast_this_year'),true);
142 cm.setHidden(cid('company_estimates'),false);
144 cm.setHidden(cid('forecast_this_year'),false);
145 cm.setHidden(cid('company_estimates'),true);
150 load : function (_self, records, options)
152 var sm = _this.grid.getSelectionModel();
153 Roo.each(records, function(record){
154 if(record.data.item_id == _this.grid.lastSelectedId){
155 sm.selectRow(_this.grid.ds.indexOf(record));
157 _this.sgrid.footer.onClick('first');
164 sortInfo : { field : 'item_number', direction: 'ASC' },
169 url : baseURL + '/Roo/Item.php'
176 totalProperty : 'total',
179 'name': 'item_number',
183 'name': 'item_descrip1',
187 'name': 'total_before_last_year',
191 'name': 'total_last_year',
195 'name': 'forecast_this_year',
199 'name': 'total_this_year',
203 'name': 'total_next_year',
207 'name': 'forecast_next_year',
211 'name': 'last_forecast_entered',
218 xtype: 'PagingToolbar',
221 displayMsg : "Displaying Item{0} - {1} of {2}",
222 emptyMsg : "No Item found",
233 render : function (_self)
235 _this.brandSel = _self;
238 select : function (combo, record, index)
240 _this.wgrid.ds.load({});}
244 displayField : 'charass_value',
246 emptyText : "Select Brand",
247 forceSelection : true,
249 loadingText : "Searching...",
252 qtip : "Select Brand",
253 queryParam : 'query[charass_value]',
254 selectOnFocus : true,
255 tpl : '<div class="x-grid-cell-text x-btn button"><b>{charass_value}</b> </div>',
256 triggerAction : 'all',
262 beforeload : function (_self, o)
264 o.params = o.params || {};
265 // staff can see all logs, other companies can only see their own.
266 // look for all of the charass 's with the same type= eg. brand.
268 o.params.charass_char_id_char_name = 'BRAND';
269 o.params.charass_target_type ='I';
270 o.params._distinct = 'charass_value';
271 o.params._columns = 'charass_value';
276 sortInfo : { field : 'charass_value' , direction : 'ASC' },
281 url : baseURL + '/Roo/Charass.php'
288 totalProperty : 'total',
295 'name': 'person_name',
299 'name': 'event_when',
301 'dateFormat': 'Y-m-d'
328 'name': 'person_id_id',
332 'name': 'person_id_office_id',
336 'name': 'person_id_name',
340 'name': 'person_id_phone',
344 'name': 'person_id_fax',
348 'name': 'person_id_email',
352 'name': 'person_id_company_id',
356 'name': 'person_id_role',
360 'name': 'person_id_active',
364 'name': 'person_id_remarks',
368 'name': 'person_id_passwd',
372 'name': 'person_id_owner_id',
376 'name': 'person_id_lang',
380 'name': 'person_id_no_reset_sent',
384 'name': 'person_id_action_type',
388 'name': 'person_id_project_id',
392 'name': 'person_id_deleted_by',
396 'name': 'person_id_deleted_dt',
407 render : function (_self)
409 _this.groupSel = _self;
411 select : function (combo, record, index)
413 _this.wgrid.ds.load({});
418 displayField : 'charass_value',
420 emptyText : "Select Product Group",
421 forceSelection : true,
423 loadingText : "Searching...",
426 qtip : "Select Product Group",
427 queryParam : 'query[charass_value]',
428 selectOnFocus : true,
429 tpl : '<div class="x-grid-cell-text x-btn button"><b>{charass_value}</b> </div>',
430 triggerAction : 'all',
436 beforeload : function (_self, o)
438 o.params = o.params || {};
439 // staff can see all logs, other companies can only see their own.
440 // look for all of the charass 's with the same type= eg. brand.
442 o.params.charass_char_id_char_name = 'PRODUCTGROUP';
443 o.params.charass_target_type ='I';
444 o.params._distinct = 'charass_value';
445 o.params._columns = 'charass_value';
450 sortInfo : { field : 'charass_value' , direction : 'ASC' },
455 url : baseURL + '/Roo/Charass.php'
462 totalProperty : 'total',
469 'name': 'person_name',
473 'name': 'event_when',
475 'dateFormat': 'Y-m-d'
502 'name': 'person_id_id',
506 'name': 'person_id_office_id',
510 'name': 'person_id_name',
514 'name': 'person_id_phone',
518 'name': 'person_id_fax',
522 'name': 'person_id_email',
526 'name': 'person_id_company_id',
530 'name': 'person_id_role',
534 'name': 'person_id_active',
538 'name': 'person_id_remarks',
542 'name': 'person_id_passwd',
546 'name': 'person_id_owner_id',
550 'name': 'person_id_lang',
554 'name': 'person_id_no_reset_sent',
558 'name': 'person_id_action_type',
562 'name': 'person_id_project_id',
566 'name': 'person_id_deleted_by',
570 'name': 'person_id_deleted_dt',
587 var brand = _this.brandSel.getValue();
588 var group = _this.groupSel.getValue();
590 if(!brand && !group){
591 Roo.MessageBox.alert('Error','Please select the brand or group');
595 Roo.MessageBox.alert("Notice","Your report should be downloading now");
598 url : baseURL + '/Roo/Salesforecast',
610 cls : 'x-btn-text-icon',
611 text : "Download Report",
612 icon : rootURL + '/Pman/templates/images/spreadsheet.gif'
618 xtype: 'ColumnModel',
620 dataIndex : 'itemsrc_active',
621 header : 'is Active?',
623 renderer : function(v) {
624 var state = v * 1 > 0 ? '-checked' : '';
626 return '<img class="x-grid-check-icon' + state + '" src="' + Roo.BLANK_IMAGE_URL + '"/>';
631 xtype: 'ColumnModel',
633 dataIndex : 'item_number',
634 header : 'Item code',
636 renderer : function(v) { return String.format('{0}', v); }
639 xtype: 'ColumnModel',
641 dataIndex : 'item_descrip1',
642 header : 'Item name',
644 renderer : function(v) { return String.format('{0}', v); }
647 xtype: 'ColumnModel',
649 dataIndex : 'total_before_last_year',
652 renderer : function(v) { return String.format('{0}', v); }
655 xtype: 'ColumnModel',
657 dataIndex : 'total_last_year',
660 renderer : function(v) { return String.format('{0}', v); }
663 xtype: 'ColumnModel',
665 dataIndex : 'forecast_this_year',
668 renderer : function(v,x,r) {
672 return '<span style="color:red">' + v + '</span>';
675 return String.format('{0}', v);
681 xtype: 'ColumnModel',
683 dataIndex : 'total_this_year',
686 renderer : function(v) { return String.format('{0}', v); }
689 xtype: 'ColumnModel',
691 dataIndex : 'forecast_next_year',
695 renderer : function(v,x,r) {
699 return '<span style="color:red">' + v + '</span>';
702 return String.format('{0}', v);
708 xtype: 'ColumnModel',
710 dataIndex : 'last_forecast_entered',
711 header : 'Last forcast entered',
713 renderer : function(v,x,r) {
717 var last_forecast = new Date(v);
719 var date = new Date();
720 var y = date.getFullYear();
721 var m = date.getMonth() + 3;
722 var d = date.getDate();
727 var c = new Date(y,m,d);
728 if (last_forecast < c) {
729 return '<span style="color:red">' + last_forecast.format('M Y') + '</span>';
732 return String.format('{0}', last_forecast.format('M Y'));
738 xtype: 'ColumnModel',
740 dataIndex : 'company_estimates',
741 header : 'Estimates',
744 renderer : function(v,x,r) {
745 return String.format('{0}', v);
757 activate : function() {
760 _this.wgrid.ds.load({});
768 tableName : 'custinfo',
777 if (_this.wpanel.active) {
778 _this.wgrid.ds.load({});
781 rowclick : function (_self, rowIndex, e)
783 var sm = _this.grid.getSelectionModel();
784 if(sm.getSelections().length){
785 _this.grid.lastSelectedId = sm.getSelections()[0].data.item_id;
787 _this.grid.footer.onClick('refresh');
790 autoExpandColumn : 'cust_name_with_pcs',
796 beforeload : function (_self, o){
797 o.params = o.params || {};
799 o.params._with_lastyear_total = 1;
800 o.params._columns = 'cust_id,cust_name,lastyear_total';
802 var brand = _this.brandSel.getValue();
804 _this.wgrid.ds.removeAll();
805 _this.grid.ds.removeAll();
809 o.params._charass_brand_value = _this.brandSel.getValue();
810 o.params._charass_group_value = _this.groupSel.getValue();
812 o.params.limit = 9999;
815 load : function (_self, records, options)
817 var sm = _this.wgrid.getSelectionModel();
818 if (!sm.getSelections().length) {
822 _this.grid.footer.onClick('first');
826 sortInfo : { field : 'lastyear_total', direction: 'DESC' },
831 url : baseURL + '/Roo/Custinfo.php'
838 totalProperty : 'total',
845 'name': 'cust_name_with_pcs',
849 'name': 'lastyear_total',
857 xtype: 'ColumnModel',
859 dataIndex : 'cust_name',
860 header : 'Company Name',
862 renderer : function(v) { return String.format('{0}', v); }
865 xtype: 'ColumnModel',
867 dataIndex : 'lastyear_total',
870 renderer : function(v,x,r)
872 return String.format('{0}', v + ' pcs');
880 xtype: 'LayoutRegion',
884 xtype: 'LayoutRegion',
896 activate : function() {
898 /* if (_this.sgrid) {
899 _this.sgrid.footer.onClick('first');
907 tableName : 'Groups',
916 //_this.dialog = Pman.Dialog.FILL_IN
917 /* if (_this.spanel.active) {
918 this.footer.onClick('first');
921 afteredit : function (e)
923 _this.grid.loadMask.el.unmask();
924 _this.wgrid.loadMask.el.unmask();
925 if(e.value == e.originalValue){
929 var salesforecast_id = e.record.json[field + '_salesforecast_id'];
930 var rec = _this.grid.getSelectionModel().getSelected();
931 var s = _this.wgrid.getSelectionModel().getSelected();
934 Roo.Msg.alert("Error","Please select a item");
939 salesforecast_id : (salesforecast_id * 1 > 0) ? salesforecast_id : 0,
940 salesforecast_cust_id : (s.data.cust_id < 0) ? 0 : s.data.cust_id,
941 salesforecast_is_all_buyers : (s.data.view_type) == 'All' ? 1 : 0,
942 _item_id : rec.data.item_id,
944 year : e.record.data['year']
947 if(s.data.cust_id > 0){ // company level confirm and request editable!
948 if(e.record.data['type'] == 'confirm'){
949 params.salesforecast_qty = e.value;
951 if(e.record.data['type'] == 'request'){
952 params.salesforecast_requests = e.value;
954 } else { // item level estimated and total forecast editable!
955 if(e.record.data['type'] == 'estimated'){
956 params.salesforecast_qty = e.value;
958 if(e.record.data['type'] == 'forecast'){
959 params.salesforecast_sum = e.value;
965 url : baseURL + '/Roo/Salesforecast.php',
968 success : function() {
970 _this.sgrid.footer.onClick('first');
976 beforeedit : function (e)
979 var y = new Date().getFullYear();
980 var m = new Date().getMonth(); // 0-11
981 var s = _this.grid.getSelectionModel().getSelected();
982 var ss = _this.wgrid.getSelectionModel().getSelected();
985 if(rec.data.type != 'forecast' || rec.data.year != y || !s.data.itemsrc_active || e.column < m + 3){
\r
990 if(s.data.itemsrc_active * 1 < 1 || (rec.data.year == y && e.column < m + 3) || (rec.data.year != y && e.column + 12 < m + 3)){
993 if(ss.data.cust_id > 0){ // companies level, confirm and request editable!
994 if(rec.data.type != 'confirm' && rec.data.type != 'request'){
997 }else{ // item level, estimated and total forecast editable!
998 if(rec.data.type != 'estimated' && rec.data.type != 'forecast'){
1003 _this.grid.loadMask.el.mask('Cancel edit forecast first!');
1004 _this.wgrid.loadMask.el.mask('Cancel edit forecast first!');
\r
1007 autoExpandColumn : 'year_text',
1010 calcest : function(colname)
1013 var before = _this.sgrid.ds.getAt(0).data[colname];
1014 var last = _this.sgrid.ds.getAt(1).data[colname];
1016 if(before < last * 2){
1017 est = last * 2 - before;
1021 formatcol : function(v,r,n)
1024 var y = d.getFullYear();
1025 var m = d.getMonth();
1026 var month = n.split("_");
1027 // var est = _this.sgrid.calcest(n);
1028 /* if(r.data.type == 'forecast' && r.data.year == y && r.json.is_all_buyers == 0){
1029 if(month[1] < m + 3)
1030 { // fill in blank if the month less than next month
1031 return String.format('{0}','');
1033 if(est > v || v > est * 2 || v * 1 == 0)
1034 { //red if forcast is less than estimate or double estimate
1035 return '<span style="color:red">' + v + ' ( ' + est + ' )</span>';
1037 return String.format('{0}',v + ' ( ' + est + ' )');
1039 if(r.data.type == 'forecast' && r.data.year == y && r.json.is_all_buyers == 1){
1041 if((typeof(v) != undefined && v > 0)){
1044 if(typeof(r.json[n + '_sum']) != undefined && r.json[n + '_sum'] > 0){
1045 t += 'sum( ' + r.json[n + '_sum'] + ' )';
1047 if(month[1] > m + 2 && month[1] < m + 7 && !t){
1048 return '<span style="color:red">MUST FILL IN (' + est + ')</span>';
1050 return String.format('{0}',t);
1054 var s = _this.wgrid.getSelectionModel().getSelected();
1056 // forecast - item level
1059 if(r.data.type == 'confirm' && s.data.cust_id < 0 && v){
1060 return String.format('SUM ( {0} )',v);
1063 if(r.data.type == 'percentage' && v){
1064 return String.format('<span style="color:green">{0}%</span>', Roo.util.Format.number(v,2));
1067 if(r.data.type == 'predicted' && v < 0){
1068 return String.format('<span style="color:red">{0}</span>', 'BAD GUESS');
1072 return String.format('{0}',v);
1079 beforeload : function (_self, o)
1081 o.params = o.params || {};
1083 var rec = _this.grid.getSelectionModel().getSelected();
1084 var s = _this.wgrid.getSelectionModel().getSelected();
1086 if(!_this.grid || !rec || !s){
1091 o.params._detailView = 1;
1092 o.params._item_id = rec.data.item_id;
1093 o.params._in_cust_id = (s.data.cust_id < 0) ? 0 : s.data.cust_id;
\r
1094 o.params._is_all_buyers = (s.data.view_type) == 'All' ? 1 : 0;
1099 sortInfo : { field : 'name', direction: 'ASC' },
1104 url : baseURL + '/Roo/Salesforecast.php'
1107 xtype: 'JsonReader',
1111 totalProperty : 'total',
1166 'name': 'year_text',
1188 click : function (_self, e)
1191 var m = d.getMonth(); // getMonth -> 0-11
1192 var y = new Date().getFullYear();
1194 var salesforecasts = [];
1196 var salesforecast_id = 0;
1198 var rec = _this.grid.getSelectionModel().getSelected();
\r
1199 var s = _this.wgrid.getSelectionModel().getSelected();
1201 Roo.Msg.alert("Error","Please select a item");
1204 if(rec.data.itemsrc_active * 1 < 1 ){
1205 Roo.Msg.alert("Error","The itemsrc is not active!");
1208 if(s.data.cust_id < 0){
1209 Roo.Msg.alert("Error","Auto Fill Just happen on company level, please select a company!");
1213 for(var i = 3; i < 13 - m; i++){ // current month and the next month are not able to edit.
1215 var salesforecast = {};
1217 salesforecast_id = _this.sgrid.ds.getAt(3).json['total_' + (m + i) + '_salesforecast_id']; // check existing or not ???
1218 est = _this.sgrid.ds.getAt(2).json['total_' + (m + i)]; // estimated qty!
1219 qty = _this.sgrid.ds.getAt(3).json['total_' + (m + i)]; // existing qty!
1221 salesforecast['month'] = m + i; // period month
1222 salesforecast['year'] = y; // period year
1224 salesforecast['salesforecast_id'] = (salesforecast_id * 1 > 0) ? salesforecast_id : 0; // update or insert ???
1225 salesforecast['salesforecast_qty'] = (qty != 0) ? qty : est; // if we have entried in this period. do not use the estimated
1227 salesforecast['_item_id'] = rec.data.item_id;
1229 salesforecast['salesforecast_cust_id'] = s.data.cust_id;
1231 salesforecast['salesforecast_is_all_buyers'] = 0;
1233 salesforecasts.push((salesforecast));
1236 if(!salesforecasts.length){
1240 url : baseURL + '/Roo/Salesforecast.php',
1243 _group_data : Roo.encode(salesforecasts)
1246 success : function() {
1248 _this.sgrid.footer.onClick('first');
1256 text : "Auto Fill (This Year)"
1261 xtype: 'PagingToolbar',
1265 displayMsg : "Displaying Groups{0} - {1} of {2}",
1266 emptyMsg : "No Groups found"
1270 xtype: 'ColumnModel',
1272 dataIndex : 'year_text',
1273 header : 'Scenario / Month',
1275 renderer : function(v) { return String.format('{0}', v); }
1278 xtype: 'ColumnModel',
1280 dataIndex : 'total_1',
1283 renderer : function(v,x,r)
1285 return _this.sgrid.formatcol(v,r,this.name);
1288 xtype: 'GridEditor',
1291 xtype: 'NumberField',
1293 allowDecimals : false
1298 xtype: 'ColumnModel',
1300 dataIndex : 'total_2',
1303 renderer : function(v,x,r)
1305 return _this.sgrid.formatcol(v,r,this.name);
1308 xtype: 'GridEditor',
1311 xtype: 'NumberField',
1313 allowDecimals : false
1318 xtype: 'ColumnModel',
1320 dataIndex : 'total_3',
1323 renderer : function(v,x,r)
1325 return _this.sgrid.formatcol(v,r,this.name);
1328 xtype: 'GridEditor',
1331 xtype: 'NumberField',
1333 allowDecimals : false
1338 xtype: 'ColumnModel',
1340 dataIndex : 'total_4',
1343 renderer : function(v,x,r)
1345 return _this.sgrid.formatcol(v,r,this.name);
1348 xtype: 'GridEditor',
1351 xtype: 'NumberField',
1353 allowDecimals : false
1358 xtype: 'ColumnModel',
1360 dataIndex : 'total_5',
1363 renderer : function(v,x,r)
1365 return _this.sgrid.formatcol(v,r,this.name);
1368 xtype: 'GridEditor',
1371 xtype: 'NumberField',
1373 allowDecimals : false
1378 xtype: 'ColumnModel',
1380 dataIndex : 'total_6',
1383 renderer : function(v,x,r)
1385 return _this.sgrid.formatcol(v,r,this.name);
1388 xtype: 'GridEditor',
1391 xtype: 'NumberField',
1393 allowDecimals : false
1398 xtype: 'ColumnModel',
1400 dataIndex : 'total_7',
1403 renderer : function(v,x,r)
1405 return _this.sgrid.formatcol(v,r,this.name);
1408 xtype: 'GridEditor',
1411 xtype: 'NumberField',
1413 allowDecimals : false
1418 xtype: 'ColumnModel',
1420 dataIndex : 'total_8',
1423 renderer : function(v,x,r)
1425 return _this.sgrid.formatcol(v,r,this.name);
1428 xtype: 'GridEditor',
1431 xtype: 'NumberField',
1433 allowDecimals : false
1438 xtype: 'ColumnModel',
1440 dataIndex : 'total_9',
1443 renderer : function(v,x,r)
1445 return _this.sgrid.formatcol(v,r,this.name);
1448 xtype: 'GridEditor',
1451 xtype: 'NumberField',
1453 allowDecimals : false
1458 xtype: 'ColumnModel',
1460 dataIndex : 'total_10',
1463 renderer : function(v,x,r)
1465 return _this.sgrid.formatcol(v,r,this.name);
1468 xtype: 'GridEditor',
1471 xtype: 'NumberField',
1473 allowDecimals : false
1478 xtype: 'ColumnModel',
1480 dataIndex : 'total_11',
1483 renderer : function(v,x,r)
1485 return _this.sgrid.formatcol(v,r,this.name);
1488 xtype: 'GridEditor',
1491 xtype: 'NumberField',
1493 allowDecimals : false
1498 xtype: 'ColumnModel',
1500 dataIndex : 'total_12',
1503 renderer : function(v,x,r)
1505 return _this.sgrid.formatcol(v,r,this.name);
1508 xtype: 'GridEditor',
1511 xtype: 'NumberField',
1513 allowDecimals : false
1518 xtype: 'ColumnModel',
1520 dataIndex : 'total_year',
1523 renderer : function(v) { return String.format('{0}', v); }
1530 xtype: 'LayoutRegion',
1534 xtype: 'LayoutRegion',