// NOTE: [This JS must loaded as last item]
var PSACTUAL_DGV_COLUMN_COUNTS = -1;

	// ===============================================================
	// Initialize Form
	// ===============================================================
	function NEW_SCHEDULE_PREPARE_DGV_COLS_COUNT()
	{
		// Abort if already populated
		// _______________________________________________________________________
		if(PSACTUAL_DGV_COLUMN_COUNTS >= 0)
		{
			return;
		}
		
		// Initialize
		// _______________________________________________________________________
		var COL_INDEX = 1;
		var CURRENT_POSTFIX = "";
		
		// Loop indexes to count columns
		// _______________________________________________________________________
		CURRENT_POSTFIX = JSVC_STR.VAR_FIX(COL_INDEX.toString(), null, 2, 2, "0");
		while(JSOC_ELEMENT.VAR_ELEMENT_EXISTS("PSACTUAL_DGV_HEADER_REC_PSACTUAL_QTY_" + CURRENT_POSTFIX))
		{
			COL_INDEX ++;
			CURRENT_POSTFIX = JSVC_STR.VAR_FIX(COL_INDEX.toString(), null, 2, 2, "0");
		}
			
		// Update Column Counts
		// _______________________________________________________________________
		COL_INDEX --;
		PSACTUAL_DGV_COLUMN_COUNTS = COL_INDEX;	
	};
	
	
	// ===============================================================
	// Initialize Form
	// ===============================================================
	function NEW_SCHEDULE_PREPARE_DGV_COLS_CLEAR()
	{
		// Initialize
		// _______________________________________________________________________
		var CURRENT_POSTFIX = "";
		var DATE_INDEX = 1;
		
		// Prepare Columns
		// _______________________________________________________________________
		while(PSACTUAL_DGV_COLUMN_COUNTS >= DATE_INDEX)
		{
			// Update Branch
			// ...........................................
			CURRENT_POSTFIX = JSVC_STR.VAR_FIX(DATE_INDEX.toString(), null, 2, 2, "0");
			JSOC_ELEMENT.VAR_INNER_HTML("PSACTUAL_DGV_HEADER_REC_PSACTUAL_QTY_" + CURRENT_POSTFIX, '-');
			
			// Update Date
			// ...........................................
			JSOC_ELEMENT.VAR_INNER_HTML
			(
				PSACTUAL_DGV.COLUMN.HEADER_ELEMENT("REC_PSACTUAL_ID_" + CURRENT_POSTFIX), 
				'0'
			);
			JSOC_ELEMENT.VAR_INNER_HTML
			(
				PSACTUAL_DGV.COLUMN.HEADER_ELEMENT("ACC_GROUP_ID_" + CURRENT_POSTFIX), 
				'0'
			);
			JSOC_ELEMENT.VAR_INNER_HTML
			(
				PSACTUAL_DGV.COLUMN.HEADER_ELEMENT("REC_PSACTUAL_QTY_" + CURRENT_POSTFIX), 
				'-'
			);
				
			// Show Columns
			// ...........................................
			JSOC_STYLE.VAR_DISPLAY(PSACTUAL_DGV.COLUMN.HEADER_ELEMENT("REC_PSACTUAL_QTY_" + CURRENT_POSTFIX), 'DEFAULT');
			JSOC_STYLE.VAR_DISPLAY(PSACTUAL_DGV.COLUMN.ITEM("REC_PSACTUAL_QTY_" + CURRENT_POSTFIX), 'DEFAULT');
			
			// To Next Loop
			// ...........................................
			DATE_INDEX ++;
		}
	};
	
	
	// ===============================================================
	// Initialize Form
	// ===============================================================
	function NEW_SCHEDULE_PREPARE_DGV_COLS(SCHEDULE_TIME)
	{
		NEW_SCHEDULE_PREPARE_DGV_COLS_COUNT();
		
		// ~~~~~
		
		var CALLBACK_METHOD = function(IS_SUCCESS, RESPONSE_STRING)
		{
			// Validate
			// _______________________________________________________________________
			if(IS_SUCCESS === false)
			{
				CUS_SEND_DIALOG_TRY_DISMISS();
				console.error("CONNECTION ERROR: \n" + RESPONSE_STRING);
				return;
			}
			
			// Validate JSON Response
			// _______________________________________________________________________
			var JSON_OBJECT = JSRC_JSON.REF_CREATE(RESPONSE_STRING);
			if(JSRC_JSON.REF_IS_SUCCESS(JSON_OBJECT) === false)
			{
				CUS_SEND_DIALOG_TRY_DISMISS();
				console.error("REQUEST ERROR: \n" + RESPONSE_STRING);
				return;
			}
			
			// Back to DGV Top
			// _______________________________________________________________________	
			if(LOAD_PAGING_IGNORE_NEXT_REQUEST == true)
			{
				JSOC_ELEMENT.VAR_GET("PSACTUAL_DGV").scrollIntoView
				(
					{
				  		behavior: 'auto', 
				  		block: 'start'
					}
				);		
			}
			
			// JSON Empty (Clears the DataGrodView)
			// _______________________________________________________________________
			if(JSRC_JSON.REF_READ(JSON_OBJECT, "JSON_COUNT") <= 0)
			{
				CUS_SEND_DIALOG_TRY_DISMISS();
				PSACTUAL_DGV.ROW.CLEAR();
				NEW_SCHEDULE_PREPARE_DGV_COLS_COUNT();
				return;
			}
				
			// Populate Columns
			// _______________________________________________________________________
			POPULATE_METHOD(JSON_OBJECT);
			
		};
		
		// ~~~~~
		
		var POPULATE_METHOD = function(JSON_OBJECT)
		{
			// Initialize
			// _______________________________________________________________________
			var JSON_INDEX = 1;
			var JSON_COUNT = JSRC_JSON.REF_READ_NVALL(JSON_OBJECT, "JSON_COUNT");
			var CURRENT_POSTFIX = "";
			
			// Prepare Columns
			// _______________________________________________________________________
			while(JSON_COUNT >= JSON_INDEX)
			{
				CURRENT_POSTFIX = JSVC_STR.VAR_FIX(JSON_INDEX.toString(), null, 2, 2, "0");
				
				// Add Branch
				// ...........................................
				JSOC_ELEMENT.VAR_INNER_HTML
				(
					PSACTUAL_DGV.COLUMN.HEADER_ELEMENT("ACC_GROUP_ID_" + CURRENT_POSTFIX), 
					JSRC_JSON.REF_READ_NVALL(JSON_OBJECT, "ACC_GROUP_ID", JSON_INDEX)
				);
				JSOC_ELEMENT.VAR_INNER_HTML
				(
					PSACTUAL_DGV.COLUMN.HEADER_ELEMENT("REC_PSACTUAL_QTY_" + CURRENT_POSTFIX), 
					JSRC_JSON.REF_READ(JSON_OBJECT, "ACC_GROUP_DESCRIPTION", JSON_INDEX)
				);
				
				// To Next Loop
				// ...........................................
				JSON_INDEX ++;
			}			
			
			// Hide Unused Columns
			// _______________________________________________________________________
			while(PSACTUAL_DGV_COLUMN_COUNTS >= JSON_INDEX)
			{
				// Hide Column
				// ...........................................
				CURRENT_POSTFIX = JSVC_STR.VAR_FIX(JSON_INDEX.toString(), null, 2, 2, "0");
				JSOC_STYLE.VAR_DISPLAY(PSACTUAL_DGV.COLUMN.HEADER_ELEMENT("REC_PSACTUAL_QTY_" + CURRENT_POSTFIX), 'NONE');
				JSOC_STYLE.VAR_DISPLAY(PSACTUAL_DGV.COLUMN.ITEM("REC_PSACTUAL_QTY_" + CURRENT_POSTFIX), 'NONE');
				
				// To Next Loop
				// ...........................................
				JSON_INDEX ++;				
			}
			
			// Prepare Rows
			// _______________________________________________________________________		
			NEW_SCHEDULE_PREPARE_DGV_ROWS(SCHEDULE_TIME, CALLBACK_METHOD)
		};
		
		// ~~~~~
		
		GET_MAP_ARRAY = JSCUS_SQL._ACCOUNT._GROUP.CUS_PREPARE_MAPPED_ARRAY_FOR_GET();	
		JSVC_MAP_ARRAY.VAR_SET(GET_MAP_ARRAY, 'PARAM_ACC_GROUP_STATUS', 2);
		JSVC_MAP_ARRAY.VAR_SET(GET_MAP_ARRAY, 'PARAM_ACC_GROUP_SYSTEM_GENERATED', 1);
		NEW_SCHEDULE_PREPARE_DGV_COLS_CLEAR();
		
		JSCUS_SQL._ACCOUNT._GROUP.CUS_GET
		(
			GET_MAP_ARRAY,
			CALLBACK_METHOD,
			true
		); 
	};
	
	
	// ===============================================================
	// Initialize Form
	// ===============================================================
	function NEW_SCHEDULE_PREPARE_DGV_ROWS(SCHEDULE_TIME, CALLBACK_METHOD = null)
	{
		// Clear DGV
		// _______________________________________________________________________
		PSACTUAL_DGV.ROW.CLEAR();
		
		
		var MIXTURE_CALLBACK = function(IS_SUCCESS, RESPONSE_STRING)
		{
			CUS_SEND_DIALOG_TRY_DISMISS();
			
			// Validate
			// ...........................................
			if(IS_SUCCESS === false)
			{
				console.error("CONNECTION ERROR: \n" + RESPONSE_STRING);
				return;
			}
			
			// Validate JSON Response
			// ...........................................
			var JSON_OBJECT = JSRC_JSON.REF_CREATE(RESPONSE_STRING);
			if(JSRC_JSON.REF_IS_SUCCESS(JSON_OBJECT) === false)
			{
				console.error("REQUEST ERROR: \n" + RESPONSE_STRING);
				return;
			}
			
			// Nothing to populate
			// ...........................................
			if(JSRC_JSON.REF_READ(JSON_OBJECT, "JSON_COUNT") <= 0)
			{
				JSOC_DIALOG.VAR_MESSAGE_BOX
				(
					'There is no products in the system.', 
					'Information',
					'OK', 'INFO',
					function(MESSAGE_RESPONSE)
					{
						return;
					}
				);	
				return;								
			}
							
			// Populate Rows
			// ...........................................
			var COL_INDEX = 0;
			var COL_POSTFIX = '';
			var ROW_COUNT = JSRC_JSON.REF_READ_NVALL(JSON_OBJECT, "JSON_COUNT");
			var ROW_INDEX = 0;
			var JSON_INDEX = 1;
			
			while(ROW_COUNT >= JSON_INDEX)
			{
				PSACTUAL_DGV.ROW.ADD();
				ROW_INDEX = PSACTUAL_DGV.ROW.COUNT() - 1;
				
				// Populate Items
				PSACTUAL_DGV.CELL.VALUE("REC_PSACTUAL_DATE", ROW_INDEX, JSVC_DATE.VAR_FORMAT(SCHEDULE_TIME, 'YYYY-MM-DD HH:mm:ss') + '.000000');
				PSACTUAL_DGV.CELL.VALUE("REC_PSACTUAL_CAT_PRODUCT_ID", ROW_INDEX, JSRC_JSON.REF_READ_NVALL(JSON_OBJECT, "CAT_PRODUCT_ID", JSON_INDEX));
				PSACTUAL_DGV.CELL.VALUE("CAT_PRODUCT_DESCRIPTION", ROW_INDEX, JSRC_JSON.REF_READ(JSON_OBJECT, "CAT_PRODUCT_DESCRIPTION", JSON_INDEX));			
				
				PSACTUAL_DGV.CELL.VALUE("YIELD", ROW_INDEX, JSRC_JSON.REF_READ(JSON_OBJECT, "CAT_PRODUCT_MIXTURE_QTY", JSON_INDEX));
				if(JSRC_JSON.REF_READ_NVAL(JSON_OBJECT, "CAT_PRODUCT_MIXTURE_QTY", JSON_INDEX) != 0)
				{
					PSACTUAL_DGV.CELL.VALUE
					(
						"COST", ROW_INDEX, 
						JSVC_NUM.VAR_ROUND
						(
							JSRC_JSON.REF_READ_NVAL(JSON_OBJECT, "CAT_PRODUCT_MIXTURE_COST", JSON_INDEX) / 
							JSRC_JSON.REF_READ_NVAL(JSON_OBJECT, "CAT_PRODUCT_MIXTURE_QTY", JSON_INDEX), 
							2
						)
					);	
				}
				else
				{
					PSACTUAL_DGV.CELL.VALUE
					(
						"COST", ROW_INDEX, 
						JSRC_JSON.REF_READ_NVAL(JSON_OBJECT, "CAT_PRODUCT_MIXTURE_COST", JSON_INDEX)
					);					
				}
				PSACTUAL_DGV.CELL.VALUE("PASS_ON", ROW_INDEX, JSRC_JSON.REF_READ(JSON_OBJECT, "CAT_PRODUCT_ING_PRICE", JSON_INDEX));						
				
				// Populate columns (branches)
				COL_INDEX = 1;
				while(PSACTUAL_DGV_COLUMN_COUNTS > COL_INDEX)
				{
					COL_POSTFIX = JSVC_STR.VAR_FIX(COL_INDEX.toString(), null, 2, 2, "0");	
					
					PSACTUAL_DGV.CELL.VALUE("REC_PSACTUAL_ID_" + COL_POSTFIX, ROW_INDEX, "-1");		
					PSACTUAL_DGV.CELL.VALUE
					(
						"ACC_GROUP_ID_" + COL_POSTFIX, ROW_INDEX, 
						JSOC_ELEMENT.VAR_INNER_HTML(PSACTUAL_DGV.COLUMN.HEADER_ELEMENT("ACC_GROUP_ID_" + COL_POSTFIX))
					);		
					PSACTUAL_DGV.CELL.VALUE
					(
						"REC_PSACTUAL_QTY_" + COL_POSTFIX, ROW_INDEX, "0"
					);

			
					COL_INDEX ++;				
				}

				// To next loop
				PSACTUAL_DGV.COLUMN.AUTO_COMPUTE_EXECUTE(ROW_INDEX);
				JSON_INDEX ++;
			}
			
			// Reset Modified Status
			// ...........................................
			EDIT_HANDLER.REF_IS_MODIFIED = false;
			PSACTUAL_DGV.ROW.REFRESH_ROW_COUNT();
			
			// Auto-total tool
			// ...........................................
			if(PSACTUAL_DGV.COLUMN.TOTAL_IS_READY())
			{
				PSACTUAL_DGV.COLUMN.TOTAL_REFRESH();
			}

			// Execute Callback
			// ...........................................			
			NEW_SCHEDULE_PREPARE_DGV_LOAD_PLANS(0, SCHEDULE_TIME, CALLBACK_METHOD);

			// CFormat
			// ...........................................		
			PSACTUAL_DGV.COLUMN.CFORMAT("YIELD");	
			PSACTUAL_DGV.COLUMN.CFORMAT("PASS_ON");	
		};
		
				
		// Populate Products (Mix)
		// _______________________________________________________________________
		GET_MAP_ARRAY = JSCUS_SQL._CATEGORY._PRODUCT.CUS_PREPARE_MAPPED_ARRAY_FOR_GET();	
		JSVC_MAP_ARRAY.VAR_SET(GET_MAP_ARRAY, 'PARAM_CAT_PRODUCT_HAS_RECIPE', 24);		
		JSVC_MAP_ARRAY.VAR_SET(GET_MAP_ARRAY, 'PARAM_CAT_PRODUCT_STATUS', 2);	
		
		JSCUS_SQL._CATEGORY._PRODUCT.CUS_GET
		(
			GET_MAP_ARRAY,
			MIXTURE_CALLBACK,
			true
		); 		
	};	
	
	
	
	// ===============================================================
	// Initialize Form
	// ===============================================================
	function NEW_SCHEDULE_PREPARE_DGV_LOAD_PLANS(POPULATE_ROW_INDEX, SCHEDULE_TIME, CALLBACK_METHOD = null)
	{
		console.log(POPULATE_ROW_INDEX);
		
		// Abort if last line
		if(PSACTUAL_DGV.ROW.COUNT() <= POPULATE_ROW_INDEX)
		{
			CUS_SEND_DIALOG_TRY_DISMISS();
			
			// Auto-total tool
			if(PSACTUAL_DGV.COLUMN.TOTAL_IS_READY())
			{
				PSACTUAL_DGV.COLUMN.TOTAL_REFRESH();
			}
			PSACTUAL_DGV.COLUMN.AUTO_COMPUTE_EXECUTE(null, 'SKU_RATE');
			PSACTUAL_DGV.COLUMN.AUTO_COMPUTE_EXECUTE(null, 'GM_PERCENT');
			return;
		}
		
		// ~~~~~
		
		// Handle Callback
		var CALLBACK_METHOD = function(IS_SUCCESS, RESPONSE_STRING)
		{
			// Validate
			// _______________________________________________________________________
			if(IS_SUCCESS === false)
			{
				CUS_SEND_DIALOG_TRY_DISMISS();
				console.error("CONNECTION ERROR: \n" + RESPONSE_STRING);
				return;
			}
			
			// Validate JSON Response
			// _______________________________________________________________________
			var JSON_OBJECT = JSRC_JSON.REF_CREATE(RESPONSE_STRING);
			if(JSRC_JSON.REF_IS_SUCCESS(JSON_OBJECT) === false)
			{
				CUS_SEND_DIALOG_TRY_DISMISS();
				console.error("REQUEST ERROR: \n" + RESPONSE_STRING);
				return;
			}
			
			// Back to DGV Top
			// _______________________________________________________________________	
			if(LOAD_PAGING_IGNORE_NEXT_REQUEST == true)
			{
				JSOC_ELEMENT.VAR_GET("PSACTUAL_DGV").scrollIntoView
				(
					{
				  		behavior: 'auto', 
				  		block: 'start'
					}
				);		
			}
			
			// JSON Empty (Clears the DataGrodView)
			// _______________________________________________________________________
			if(JSRC_JSON.REF_READ(JSON_OBJECT, "JSON_COUNT") <= 0)
			{
				NEW_SCHEDULE_PREPARE_DGV_LOAD_PLANS(POPULATE_ROW_INDEX + 1, SCHEDULE_TIME, CALLBACK_METHOD);
				return;
			}
				
			// Populate Columns
			// _______________________________________________________________________
			POPULATE_LINE(JSON_OBJECT);
		};
					
		// ~~~~~
		
		// Populate Line
		var POPULATE_LINE = function(JSON_OBJECT)
		{
			// Initialize
			// _______________________________________________________________________
			var CURRENT_GROUP = 0;
			var CURRENT_COL_INDEX = 1;
			var CURRENT_POSTFIX = "";
			var CURRENT_DATE_POSTFIX = JSVC_DATE.VAR_FORMAT(SCHEDULE_TIME, "DD");
			
			var JSON_COUNT = JSRC_JSON.REF_READ_NVALL(JSON_OBJECT, "JSON_COUNT");
			var JSON_INDEX = 1;
			var HAS_NON_ZERO = false;
		
		
			// Populate Data 
			// _______________________________________________________________________
			while(JSON_COUNT >= JSON_INDEX)
			{
				// Read Current Group
				// ...........................................
				CURRENT_GROUP = JSRC_JSON.REF_READ(JSON_OBJECT, "ACC_GROUP_ID", JSON_INDEX);
				
				// Locate Group given JSON from the columns
				// ...........................................
				CURRENT_COL_INDEX = 1;
				while(PSACTUAL_DGV_COLUMN_COUNTS >= CURRENT_COL_INDEX)
				{
					CURRENT_POSTFIX = JSVC_STR.VAR_FIX(CURRENT_COL_INDEX.toString(), null, 2, 2, "0");
					
					if
					(
						PSACTUAL_DGV.CELL.VALUE
						(
							"ACC_GROUP_ID_" + CURRENT_POSTFIX, POPULATE_ROW_INDEX
						) == CURRENT_GROUP
					)
					{
						PSACTUAL_DGV.CELL.VALUE
						(
							"REC_PSACTUAL_ID_" + CURRENT_POSTFIX, POPULATE_ROW_INDEX, 
							JSRC_JSON.REF_READ_NVALL(JSON_OBJECT, "ID", JSON_INDEX)
						);	
						PSACTUAL_DGV.CELL.VALUE
						(
							"REC_PSACTUAL_QTY_" + CURRENT_POSTFIX, POPULATE_ROW_INDEX, 
							JSRC_JSON.REF_READ_NVAL(JSON_OBJECT, "D" + CURRENT_DATE_POSTFIX, JSON_INDEX)
						);	
						
						if(JSRC_JSON.REF_READ_NVAL(JSON_OBJECT, "D" + CURRENT_DATE_POSTFIX, JSON_INDEX) > 0)
						{
							HAS_NON_ZERO = true;
						}			
						break;
					}			
						
					CURRENT_COL_INDEX ++;
				}
				
				// To next JSON
				// ...........................................
				JSON_INDEX ++;
			}
			
			
			// Load Preorders
			// _______________________________________________________________________
			if(HAS_NON_ZERO == false)
			{
				JSON_INDEX = 1;
				while(JSON_COUNT >= JSON_INDEX)
				{
					// Read Current Group
					// ...........................................
					CURRENT_GROUP = JSRC_JSON.REF_READ(JSON_OBJECT, "ACC_GROUP_ID", JSON_INDEX);
					
					// Locate Group given JSON from the columns
					// ...........................................
					CURRENT_COL_INDEX = 1;
					while(PSACTUAL_DGV_COLUMN_COUNTS >= CURRENT_COL_INDEX)
					{
						CURRENT_POSTFIX = JSVC_STR.VAR_FIX(CURRENT_COL_INDEX.toString(), null, 2, 2, "0");
						
						if
						(
							PSACTUAL_DGV.CELL.VALUE
							(
								"ACC_GROUP_ID_" + CURRENT_POSTFIX, POPULATE_ROW_INDEX
							) == CURRENT_GROUP
						)
						{
							PSACTUAL_DGV.CELL.VALUE
							(
								"REC_PSACTUAL_QTY_" + CURRENT_POSTFIX, POPULATE_ROW_INDEX, 
								JSRC_JSON.REF_READ_NVAL(JSON_OBJECT, "PO" + CURRENT_DATE_POSTFIX, JSON_INDEX)
							);	
							break;
						}			
							
						CURRENT_COL_INDEX ++;
					}
					
					// To next JSON
					// ...........................................
					JSON_INDEX ++;
				}				
			}
			
			
			// To next row
			// _______________________________________________________________________
			PSACTUAL_DGV.COLUMN.AUTO_COMPUTE_EXECUTE(POPULATE_ROW_INDEX);
			NEW_SCHEDULE_PREPARE_DGV_LOAD_PLANS(POPULATE_ROW_INDEX + 1, SCHEDULE_TIME, CALLBACK_METHOD);
			return;			
		};
		
		// ~~~~~
		
		// Abort if product is null (usually the TOTAL row)
		if(PSACTUAL_DGV.CELL.VALUE_NVALL("REC_PSACTUAL_CAT_PRODUCT_ID", POPULATE_ROW_INDEX) <= 0)
		{
			NEW_SCHEDULE_PREPARE_DGV_LOAD_PLANS(POPULATE_ROW_INDEX + 1, SCHEDULE_TIME, CALLBACK_METHOD);
			return;
		}
		
		// ~~~~~
		
		
		// Send Request
		JSOC_DIALOG.VAR_LOADING_SPINNER(true);
		JSCUS_SQL._RECORD._PSAPLAN.CUS_OVERVIEW
		(
			PSACTUAL_DGV.CELL.VALUE("REC_PSACTUAL_CAT_PRODUCT_ID", POPULATE_ROW_INDEX), 
			JSVC_DATE.VAR_FORMAT(JSVC_DATE.VAR_BEGIN_OF_MONTH(SCHEDULE_TIME), 'YYYY-MM-DD HH:mm:ss') + '.000000',
			CALLBACK_METHOD
		)
	};