DELIMITER //
CREATE OR REPLACE FUNCTION sys_next_no(
  p_billno_max VARCHAR(20)
) 
RETURNS VARCHAR(20)
DETERMINISTIC
BEGIN
  DECLARE v_billno VARCHAR(20);
  DECLARE v_code1 VARCHAR(10);
  DECLARE v_code2 VARCHAR(10);
  DECLARE v_code3 INT;
  
  SET v_billno = p_billno_max;
  
  IF IFNULL(v_billno, '') = '' THEN
    SET v_billno = CONCAT(DATE_FORMAT(CURDATE(), '%y%m%d'), '-001');
  ELSE
    -- Check last 3 digits
    IF REGEXP_SUBSTR(v_billno, '[0-9]{3}$') IS NOT NULL THEN
      SET v_code1 = RIGHT(v_billno, 3);
      SET v_code3 = CAST(v_code1 AS UNSIGNED) + 1;
      
      IF v_code3 < 10 THEN
        SET v_code2 = CONCAT('00', v_code3);
      ELSEIF v_code3 < 100 THEN
        SET v_code2 = CONCAT('0', v_code3);
      ELSE
        SET v_code2 = CAST(v_code3 AS CHAR);
      END IF;
      
      SET v_billno = CONCAT(LEFT(v_billno, LENGTH(v_billno) - 3), v_code2);
    -- Check last 2 digits
    ELSEIF REGEXP_SUBSTR(v_billno, '[0-9]{2}$') IS NOT NULL THEN
      SET v_code1 = RIGHT(v_billno, 2);
      SET v_code3 = CAST(v_code1 AS UNSIGNED) + 1;
      
      IF v_code3 < 10 THEN
        SET v_code2 = CONCAT('0', v_code3);
      ELSE
        SET v_code2 = CAST(v_code3 AS CHAR);
      END IF;
      
      SET v_billno = CONCAT(LEFT(v_billno, LENGTH(v_billno) - 2), v_code2);
    END IF;
  END IF;
  
  RETURN v_billno;
END //
DELIMITER ;