A more dynamic approach would be
, getting the lowest Number and the highest and building the m missing from there.
If you don't have a leading 2 like in the example 2006004 you need to pad the generated part
CREATE TABLE documents (
"order_id" VARCHAR(22),
"documentno" VARCHAR(12)
);
INSERT INTO documents
("order_id", "documentno")
VALUES
('100001110', 'VD4BC2006004'),
('100001114' ,'VD4BC2006005'),
('100001135' ,'YD4BC2006006'),
('100001166' ,'YD4BC2006007'),
('100001215' ,'YD4BC2006009'),
('100001256' ,'YD4BC2006010'),
('100001289' ,'YD4BC2006011'),
('100001332' ,'VD4BC2006013'),
('100001334' ,'VD4BC2006014'),
('100001432' ,'VD4BC2006015'),
('100000616' ,'DGP0S2003028'),
('100000617' ,'DGP0S2003029'),
('100001034' ,'DGP0S2003069');
WITH cte as (
SELECT LEFT("documentno",5) lpart , MIN(RIGHT("documentno",7)) minpart, MaX(RIGHT("documentno",7)) maxpart FROM documents
groUP BY LEFT("documentno",5))
sELECT lpart || generate_series(minpart::INTEGER, maxpart::INTEGER) as mdocumentno FROM cte
except
select documentno from documents
ORDER bY mdocumentno;
| mdocumentno |
| :----------- |
| DGP0S2003030 |
| DGP0S2003031 |
| DGP0S2003032 |
| DGP0S2003033 |
| DGP0S2003034 |
| DGP0S2003035 |
| DGP0S2003036 |
| DGP0S2003037 |
| DGP0S2003038 |
| DGP0S2003039 |
| DGP0S2003040 |
| DGP0S2003041 |
| DGP0S2003042 |
| DGP0S2003043 |
| DGP0S2003044 |
| DGP0S2003045 |
| DGP0S2003046 |
| DGP0S2003047 |
| DGP0S2003048 |
| DGP0S2003049 |
| DGP0S2003050 |
| DGP0S2003051 |
| DGP0S2003052 |
| DGP0S2003053 |
| DGP0S2003054 |
| DGP0S2003055 |
| DGP0S2003056 |
| DGP0S2003057 |
| DGP0S2003058 |
| DGP0S2003059 |
| DGP0S2003060 |
| DGP0S2003061 |
| DGP0S2003062 |
| DGP0S2003063 |
| DGP0S2003064 |
| DGP0S2003065 |
| DGP0S2003066 |
| DGP0S2003067 |
| DGP0S2003068 |
| VD4BC2006006 |
| VD4BC2006007 |
| VD4BC2006008 |
| VD4BC2006009 |
| VD4BC2006010 |
| VD4BC2006011 |
| VD4BC2006012 |
| YD4BC2006008 |
db<>fiddle here