Schedules to the Act (First & Second) and high-yield Rule schedules (C, G, H, H1, J, K, M, P, T, X, Y) Import of drugs — Section 10 prohibited classes, licensing/permit flowchart, and verified Section 13 penalty table (imprisonment/fine figures) Manufacture of drugs — Section 18 prohibitions (with flowchart), licence conditions (Schedule M/GMP), and the four special licence types (Test/Analysis, New Drug, Loan, Repacking) with a comparison flowchart Section 27 penalty ladder (3→7→10 years to life) — verified against the actual bare act text A consolidated manufacture-to-sale compliance flowchart Mnemonics throughout (MASque, MASt-P-New, TeNo-Lo-Re, 3-3-7
Drugs and Cosmetics Act 1940 Section 27 penalty ladder Schedule H H1 X import manufacture provisions bare act
https://cdsco.gov.in/opencms/export/sites/CDSCO_WEB/Pdf-docu…
Drugs Cosmetics Act 1940 Section 10 prohibited drugs list Section 18 manufacture prohibition First Schedule Second Schedule drugs list India
https://ayush.delhi.gov.in/sites/default/files/ayush/custom/…
| Entry | Reference Text |
|---|---|
| Pharmacopoeia of India (IP) | Official Indian standard |
| British Pharmacopoeia (BP) | Applies to drugs described therein |
| International Pharmacopoeia (IP/WHO) | WHO standard |
| Extra Pharmacopoeia (Martindale) | Reference for unlisted drugs |
| United States Pharmacopeia (USP) | Applicable where specified |
| British Pharmaceutical Codex (BPC) | Additional standard |
| British Veterinary Codex | Veterinary drugs |
| Ayurvedic Pharmacopoeia of India | AYUSH drugs |
| Siddha Vaidya Thirattu / Unani Pharmacopoeia | AYUSH system drugs |
| Schedule | What it Contains | Key Requirement |
|---|---|---|
| C | Biological & special products (vaccines, sera, toxoids, hormones, antibiotics injectables) | Enhanced storage/cold chain; manufacturing under stricter conditions |
| C1 | Large-volume parenterals | GMP + separate manufacturing |
| G | ~65 drugs (antihistamines, insulin, bleomycin, aminopterine, cytotoxics) | Label must carry: "CAUTION - For use only under medical supervision" |
| H | Prescription-only drugs (antibiotics, steroids, antihypertensives, etc.) | Only on RMP prescription; entry in prescription register mandatory |
| H1 | High-risk Rx drugs (3rd/4th gen cephalosporins, carbapenems, fluoroquinolones, anti-TB, antifungals) | Red strip on label; prescription retained by chemist for 2 years; cannot be repeated without fresh Rx |
| J | Diseases for which no drug may claim to be a cure | 54 diseases listed (cancer, AIDS, diabetes, etc.); any such claim = misbranding |
| K | Drugs exempt from Chapters IV/IVA in certain states/areas (Ayurveda, homeopathy) | Limited applicability |
| M | Good Manufacturing Practice (GMP) standards for premises, plant, machinery, personnel | Mandatory compliance for all licensed manufacturers (Schedule M = Indian GMP) |
| M-III | GMP for cosmetics | Separate GMP code |
| P | Life period of drugs - storage period/shelf-life guidelines | Governs expiry dating |
| T | Standards for surgical dressings, bandages, orthopaedic implants | Quality standards for these categories |
| X | Habit-forming / psychotropic drugs (morphine, pethidine, fentanyl, codeine formulations) | Strict licence (Form 20-A); dispensing only on special Rx; records kept 2 years; no advertisement |
| Y | Requirements for clinical trials (data to be submitted) | Preclinical + clinical data package for new drug approval |
┌─────────────────────────────────────────────────────────────┐
│ SECTION 10 - PROHIBITED DRUG IMPORTS │
├─────────────────────────────────────────────────────────────┤
│ (a) Not of standard quality (below First/Second Schedule) │
│ (b) Misbranded (Section 9 definition) │
│ (c) Adulterated (Section 9A definition) │
│ (d) Spurious (Section 9B definition) │
│ (ee) Cosmetic tested on animals [post-2014 amendment] │
│ (f) Without valid import licence (Form 10) │
│ (g) Any drug notified by CG under Section 10A as dangerous │
│ or lacking therapeutic value │
└─────────────────────────────────────────────────────────────┘
INTENDING IMPORTER
│
▼
Is drug in Section 10 prohibited list?
│
YES ──────────────────────────────────► IMPORT PROHIBITED
│ (unless special permit)
NO
│
▼
Obtain Licence from Central Licensing Authority (CLA / CDSCO)
┌─────────────────────────────────────┐
│ Form 10 → Regular import licence │
│ Form 11 → Import for examination/ │
│ test/analysis only │
│ Form 8 → Import of new drugs │
│ (requires clinical data)│
└─────────────────────────────────────┘
│
▼
Special Exceptions (Rule 33/33A):
┌──────────────────────────────────────────────────────┐
│ Rule 33 - Small quantities for Test/Analysis │
│ (licence Form 11 required) │
│ Rule 33-A - New drugs for life-threatening diseases │
│ (Govt hospital / autonomous institution) │
│ Rule 136 - Cosmetics for personal use (baggage) │
└──────────────────────────────────────────────────────┘
│
▼
Labelling compliance: Parts IX, X, XII of Rules
(Name, manufacturer, expiry, country of origin mandatory)
│
▼
CUSTOMS CLEARANCE (Section 11 applies Sea Customs Act 1878)
| Clause | Offence | Imprisonment | Fine |
|---|---|---|---|
| 13(1)(a) | Import of adulterated/spurious drug (Sec 9A/9B) OR animal-tested cosmetic (Sec 10, cl. ee) | Up to 3 years | Up to ₹5,000 |
| 13(1)(b) | Import of any other prohibited drug/cosmetic (Sec 10) | Up to 6 months | Up to ₹500, OR both |
| 13(1)(c) | Import in contravention of Section 10A notification | Up to 3 years | Up to ₹5,000, OR both |
| 13(2) subsequent offence | Repeat conviction under 13(1)(a) | Up to 7 years | Up to ₹5,000 |
┌────────────────────────────────────────────────────────────────┐
│ SECTION 18(a) - PROHIBITED MANUFACTURE/SALE │
├────────────────────────────────────────────────────────────────┤
│ (i) Drug not of standard quality / misbranded / adulterated │
│ / spurious │
│ (ii) Cosmetic not of standard quality / misbranded / spurious│
│ (iii) Patent/proprietary medicine without displaying true │
│ formula or active ingredient list on label │
│ (iv) Drug without a valid licence under Section 18(c) │
│ (v) Drug in contravention of any condition of the licence │
│ (vi) Drug that is a New Drug without approval under Rule 122E│
│ (vii) Any drug in violation of any notified restriction │
│ (Section 26A/26B) │
└────────────────────────────────────────────────────────────────┘
SECTION 18(b) - BANNING ADVERTISEMENTS
No drug advertisement claiming cure of a Schedule J disease
SECTION 18(c) - LICENCE MANDATORY
No manufacture without a licence granted by Licensing Authority
(Licence under Rule 68/69 for allopathic drugs)
WANT TO MANUFACTURE A DRUG FOR SALE?
│
▼
Step 1: Is it a New Drug (Rule 122E)?
│
YES ──► Get Central Govt approval (CDSCO New Drug Approval)
│ + Clinical trial data (Schedule Y)
NO
│
▼
Step 2: Is it a standard quality drug (First/Second Schedule)?
│
NO ──► PROHIBITED under Sec 18(a)(i)
│
YES
│
▼
Step 3: Apply for Manufacturing Licence
┌────────────────────────────────────────┐
│ State Licensing Authority (SLA) │
│ Application in Form 24 (allopathic) │
│ Premises inspection │
│ GMP compliance (Schedule M) │
└────────────────────────────────────────┘
│
▼
Step 4: Licence granted → Form 25 (allopathic)
│
▼
Step 5: Ongoing compliance:
- Schedule M (GMP) at all times
- Qualified Person (QP) on premises
- Testing (in-house or approved lab)
- Records / Schedule U compliance
- Annual returns
│
▼
MANUFACTURE PERMITTED
| Licence Type | Form | Who Applies | Key Features |
|---|---|---|---|
| Test/Analysis Licence (Rule 33/Form 11 for import; Form 24 category for manufacture) | Form 11 (import) | Research labs, analytical labs | Only small quantities; drug cannot be used commercially; test facility must be specified; Inspector access mandatory |
| New Drug Licence (Rule 122E/Form 44) | Form 44 | Manufacturer of a New Drug | Requires Phase I-III clinical trial data (Schedule Y); CDSCO (Central) approval mandatory; not State SLA |
| Loan Licence (Rule 69A/Form 25A) | Form 25A | Company that owns the formula but lacks its own manufacturing plant | Uses another's licensed premises + equipment; licensor must hold valid Form 25; if licensor's licence cancelled/suspended → loan licence automatically cancelled/suspended |
| Repacking Licence (Rule 74A/Form 25B) | Form 25B | Company that buys bulk drug and repackages | Qualified competent person must supervise at all times; facility must have testing arrangements; no alteration of drug substance permitted |
SPECIAL MANUFACTURE SITUATION?
│
┌─────┴──────┐
│ │
▼ ▼
Do you have Do you have
your own your own
premises? formula?
│ │
NO NO
│ │
▼ ▼
LOAN LICENCE TEST/ANALYSIS
(Form 25A) LICENCE
(Form 11/24)
│
YES (have premises but no formula)
│
▼
REPACKING LICENCE
(Form 25B)
│
Is it a brand new drug (Rule 122E)?
│
YES
│
▼
NEW DRUG LICENCE
(Form 44, CDSCO Central)
═══════════════════════════════════════════════════════════════════
SECTION 27 PENALTY LADDER
═══════════════════════════════════════════════════════════════════
Sec 27(d) │ Any other contravention (not falling in a/b/c)
│ e.g. licence condition breach, labelling error
│ ► Imprisonment up to 1 YEAR
│ ► Fine ≥ ₹20,000
│ (Court may reduce below 1 yr on recorded reasons)
─────────────────────────────────────────────────────────────────
Sec 27(c) │ Adulterated drug (Sec 17A) not likely to cause
│ death/harm BUT quality below standard
│ ► Imprisonment: 1 to 3 YEARS + fine ≥ ₹50,000
─────────────────────────────────────────────────────────────────
Sec 27(b) │ Spurious drug (Sec 17B) OR drug failing standard
│ NOT causing/likely to cause death or grievous hurt
│ ► Imprisonment: NOT < 7 YEARS, up to LIFE
│ ► Fine ≥ ₹3 lakh OR 3x value of drugs (whichever
│ more)
│ Proviso: Court may impose < 7 yrs / < ₹1 lakh
│ for adequate and special recorded reasons
─────────────────────────────────────────────────────────────────
Sec 27(a) │ Adulterated (Sec 17A) or Spurious (Sec 17B) drug
[HIGHEST] │ WHICH CAUSES/IS LIKELY TO CAUSE DEATH or GRIEVOUS
│ HARM when used for treatment/prevention/diagnosis
│ ► Imprisonment: NOT < 10 YEARS, up to LIFE
│ ► Fine ≥ ₹10 lakh OR 3x value of drugs confiscated
│ (whichever more)
│ Proviso: Court may impose < 10 yrs for adequate/
│ special reasons recorded in judgment
═══════════════════════════════════════════════════════════════════
| Previous conviction | Repeat punishment |
|---|---|
| Under Sec 27(b) (spurious, no death) | 7 years → NOT < 7 yrs, up to 10 years + fine ≥ ₹2 lakh |
| Under Sec 27(c) (adulterated, no death) | → NOT < 10 yrs, up to LIFE + fine ≥ ₹3 lakh |
| Under Sec 27(d) (other contravention) | → NOT < 2 years, up to 4 years OR fine ≥ ₹50,000, or both |
══════════════════════════════════════════════════════════════════
MANUFACTURE → DISTRIBUTION → SALE COMPLIANCE
══════════════════════════════════════════════════════════════════
[A] PRE-MANUFACTURE STAGE
┌─────────────────────────────────────────────────────────┐
│ Is it a NEW DRUG (Rule 122E)? │
│ YES → CDSCO approval + Schedule Y data (Phase I-III│
│ clinical trials) → Form 44 (New Drug Lic.) │
│ NO → Proceed to [B] │
└─────────────────────────────────────────────────────────┘
[B] LICENSING (Sec 18(c), Rule 68-69)
┌─────────────────────────────────────────────────────────┐
│ Apply to STATE Licensing Authority (SLA) │
│ Form 24 → Inspection → Schedule M GMP compliance │
│ Qualified Person (QP) on site │
│ Form 25 GRANTED │
│ │
│ OR Special licences: │
│ Loan (25A) / Repacking (25B) / Test (Form 11) │
└─────────────────────────────────────────────────────────┘
[C] MANUFACTURE (Schedule M compliance)
┌─────────────────────────────────────────────────────────┐
│ → GMP premises (Schedule M) │
│ → QP present throughout │
│ → Batch Manufacturing Record (BMR) maintained │
│ → In-process quality checks │
│ → Quarantine of finished goods pending QC release │
└─────────────────────────────────────────────────────────┘
[D] QUALITY CONTROL & TESTING
┌─────────────────────────────────────────────────────────┐
│ → Test against First/Second Schedule standards │
│ → Government Analyst testing (Sec 20-25) │
│ → Reference samples retained: │
│ - 3 yrs (no expiry date on label) │
│ - 3 months beyond expiry date │
│ → Batch release certificate by QP │
└─────────────────────────────────────────────────────────┘
[E] LABELLING & PACKAGING (Parts IX, X of Rules)
┌─────────────────────────────────────────────────────────┐
│ → Manufacturer name + address │
│ → Batch No., Date of manufacture, Expiry date │
│ → Schedule-specific labels: │
│ Sch G → "CAUTION - Medical supervision only" │
│ Sch H → "Rx" symbol │
│ Sch H1 → RED STRIP across top │
│ Sch X → Special markings + Form 20-A dispensing │
│ → Patent medicine → list all active ingredients │
│ → No false claims (Sch J disease cure prohibition) │
└─────────────────────────────────────────────────────────┘
[F] DISTRIBUTION
┌─────────────────────────────────────────────────────────┐
│ → Wholesale licence (Form 20/21) │
│ → Cold chain for Schedule C drugs │
│ → Records: invoice, stock register maintained │
└─────────────────────────────────────────────────────────┘
[G] RETAIL SALE
┌─────────────────────────────────────────────────────────┐
│ → Retail licence (Form 20) │
│ → Registered Pharmacist on premises │
│ → Prescription register for Sch H, H1, X drugs │
│ → Sch H1 prescription retained 2 years │
│ → Sch X: no repeat dispensing without fresh Rx │
│ → No Sch H/H1/X without valid prescription │
└─────────────────────────────────────────────────────────┘
[H] PENALTIES IF NON-COMPLIANT
┌─────────────────────────────────────────────────────────┐
│ Manufacture violation → Sec 27(a/b/c/d) ladder │
│ Import violation → Sec 13 ladder │
│ Subsequent offences → Sec 30 (enhanced penalties) │
│ Cognizable offence → Spurious causing death (non- │
│ bailable, cognizable) │
└─────────────────────────────────────────────────────────┘
══════════════════════════════════════════════════════════════════
| Mnemonic | Stands For | Covers |
|---|---|---|
| MASque | Misbranded, Adulterated, Spurious, quality-substandard | Prohibited drug categories (Sec 10 & Sec 18) |
| MASt-P-New | Manufacture lic, Approved premises, Standard drugs, testing, Packaging, New drug lic | Compliance checklist Sec 18 |
| TeNo-Lo-Re | Test/analysis, New drug, Loan, Repacking | 4 special licence types |
| 3-3-7-10-Life | 3 yrs (Sec 13/27c), 7 yrs (Sec 27b), 10 yrs (Sec 27a), Life | Penalty ladder |
| C Gets High | C (biological), G (caution), H (Rx), H1 (red strip) | Prescription schedules |
| J bans K M P T X Y | J (Schedule J no-cure claims), K, M (GMP), P (shelf life), T (surgical), X (habit), Y (clinical trial) | Rule Schedules reference |
Act as professsor and prepare colorful notes handbook pdf of above note for students add flow chart diagrams
mkdir -p /home/daytona/workspace/dca-handbook && ls /home/daytona/workspace/dca-handbook
Prepare handbook pdf of above notes colorful
mkdir -p /home/daytona/workspace/dca-handbook && python3 -c "import reportlab; print(reportlab.Version)"
~/dca-handbook/generate_handbook.py
#!/usr/bin/env python3
"""
Drugs & Cosmetics Act 1940 - Student Handbook PDF Generator
Colorful, professor-style notes with flowcharts and tables
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm, cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
PageBreak, HRFlowable, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.graphics.shapes import (
Drawing, Rect, String, Line, Polygon, Arrow,
Group, Circle
)
from reportlab.graphics import renderPDF
from reportlab.graphics.shapes import Drawing
from reportlab.platypus import Image
import io
# ─── COLOUR PALETTE ───────────────────────────────────────────────────────────
NAVY = colors.HexColor("#1A237E")
BLUE = colors.HexColor("#1565C0")
LTBLUE = colors.HexColor("#E3F2FD")
TEAL = colors.HexColor("#00695C")
LTTEAL = colors.HexColor("#E0F2F1")
RED = colors.HexColor("#B71C1C")
LTRED = colors.HexColor("#FFEBEE")
ORANGE = colors.HexColor("#E65100")
LTORANGE = colors.HexColor("#FFF3E0")
PURPLE = colors.HexColor("#4A148C")
LTPURPLE = colors.HexColor("#F3E5F5")
GREEN = colors.HexColor("#1B5E20")
LTGREEN = colors.HexColor("#E8F5E9")
GOLD = colors.HexColor("#F57F17")
LTGOLD = colors.HexColor("#FFFDE7")
PINK = colors.HexColor("#880E4F")
LTPINK = colors.HexColor("#FCE4EC")
GREY = colors.HexColor("#37474F")
LTGREY = colors.HexColor("#ECEFF1")
WHITE = colors.white
BLACK = colors.black
W, H = A4
# ─── STYLES ───────────────────────────────────────────────────────────────────
base_styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
cover_title = S("CoverTitle", fontName="Helvetica-Bold", fontSize=28,
textColor=WHITE, alignment=TA_CENTER, spaceAfter=8, leading=34)
cover_sub = S("CoverSub", fontName="Helvetica-Bold", fontSize=16,
textColor=LTBLUE, alignment=TA_CENTER, spaceAfter=4)
cover_info = S("CoverInfo", fontName="Helvetica", fontSize=11,
textColor=WHITE, alignment=TA_CENTER, spaceAfter=3)
part_header = S("PartHeader", fontName="Helvetica-Bold", fontSize=20,
textColor=WHITE, alignment=TA_CENTER, spaceAfter=0, leading=26)
section_hdr = S("SectionHdr", fontName="Helvetica-Bold", fontSize=14,
textColor=WHITE, alignment=TA_LEFT, spaceAfter=0, leading=18)
sub_hdr = S("SubHdr", fontName="Helvetica-Bold", fontSize=12,
textColor=NAVY, alignment=TA_LEFT, spaceAfter=4, spaceBefore=8)
body = S("Body", fontName="Helvetica", fontSize=9.5,
textColor=GREY, alignment=TA_JUSTIFY, spaceAfter=4, leading=14)
bullet_body = S("BulletBody", fontName="Helvetica", fontSize=9.5,
textColor=GREY, leftIndent=14, bulletIndent=4, spaceAfter=3, leading=13)
mnemonic = S("Mnemonic", fontName="Helvetica-Bold", fontSize=11,
textColor=PURPLE, alignment=TA_CENTER, spaceAfter=4,
backColor=LTPURPLE, borderPad=6, leading=15)
note_style = S("Note", fontName="Helvetica-Oblique", fontSize=9,
textColor=ORANGE, alignment=TA_LEFT, spaceAfter=3, leading=13)
trap_style = S("Trap", fontName="Helvetica-Bold", fontSize=9.5,
textColor=RED, alignment=TA_LEFT, spaceAfter=3, leading=13)
toc_item = S("TocItem", fontName="Helvetica", fontSize=10,
textColor=NAVY, spaceAfter=5, leading=14)
footer_sty = S("Footer", fontName="Helvetica-Oblique", fontSize=7.5,
textColor=colors.HexColor("#90A4AE"), alignment=TA_CENTER)
# ─── HELPER FLOWABLES ─────────────────────────────────────────────────────────
class ColorBanner(Flowable):
"""A full-width coloured banner with white text."""
def __init__(self, text, bg=NAVY, fg=WHITE, height=22, font_size=13, radius=4):
Flowable.__init__(self)
self.text = text
self.bg = bg
self.fg = fg
self.bh = height
self.font_size = font_size
self.radius = radius
self.width = W - 4*cm
def wrap(self, aw, ah):
self.width = aw
return aw, self.bh + 4
def draw(self):
c = self.canv
c.setFillColor(self.bg)
c.roundRect(0, 2, self.width, self.bh, self.radius, fill=1, stroke=0)
c.setFillColor(self.fg)
c.setFont("Helvetica-Bold", self.font_size)
c.drawCentredString(self.width/2, 2 + self.bh/2 - self.font_size*0.35, self.text)
class SideBadge(Flowable):
"""A left-stripe coloured box (like a callout)."""
def __init__(self, text, stripe=TEAL, bg=LTTEAL, width=None, min_height=18):
Flowable.__init__(self)
self.text = text
self.stripe = stripe
self.bg = bg
self._w = width
self.min_height = min_height
def wrap(self, aw, ah):
self._w = aw
# Estimate height from text length
chars_per_line = int(aw / 5.5)
lines = max(1, len(self.text) // chars_per_line + 1)
self._h = max(self.min_height, lines * 14 + 10)
return aw, self._h
def draw(self):
c = self.canv
c.setFillColor(self.bg)
c.rect(0, 0, self._w, self._h, fill=1, stroke=0)
c.setFillColor(self.stripe)
c.rect(0, 0, 5, self._h, fill=1, stroke=0)
c.setFillColor(GREY)
c.setFont("Helvetica", 9)
c.drawString(10, self._h/2 - 4, self.text)
def colored_table(data, col_widths, header_bg=NAVY, header_fg=WHITE,
alt_bg=LTBLUE, border=BLUE, font_size=8.5):
"""Build a nicely styled table."""
ts = TableStyle([
('BACKGROUND', (0,0), (-1,0), header_bg),
('TEXTCOLOR', (0,0), (-1,0), header_fg),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), font_size),
('ALIGN', (0,0), (-1,-1), 'LEFT'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,1), (-1,-1), font_size - 0.5),
('GRID', (0,0), (-1,-1), 0.4, border),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, alt_bg]),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING',(0,0), (-1,-1), 4),
('WORDWRAP', (0,0), (-1,-1), 1),
])
t = Table(data, colWidths=col_widths, repeatRows=1)
t.setStyle(ts)
return t
def penalty_table(data, col_widths):
ts = TableStyle([
('BACKGROUND', (0,0), (-1,0), RED),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 8.5),
('ALIGN', (0,0), (-1,-1), 'LEFT'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,1), (-1,-1), 8),
('GRID', (0,0), (-1,-1), 0.4, RED),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LTRED]),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING',(0,0), (-1,-1), 4),
])
t = Table(data, colWidths=col_widths, repeatRows=1)
t.setStyle(ts)
return t
# ─── FLOWCHART DRAWING HELPERS ────────────────────────────────────────────────
def make_box(d, x, y, w, h, text, bg, fg=WHITE, font_size=8, radius=5, border=None):
border_c = border if border else bg
d.add(Rect(x, y, w, h, rx=radius, ry=radius,
fillColor=bg, strokeColor=border_c, strokeWidth=1))
lines = text.split('\n')
line_h = font_size + 2
total_h = len(lines) * line_h
start_y = y + h/2 + total_h/2 - line_h
for line in lines:
d.add(String(x + w/2, start_y, line,
fontName="Helvetica-Bold" if lines.index(line)==0 else "Helvetica",
fontSize=font_size, fillColor=fg,
textAnchor="middle"))
start_y -= line_h
def arrow_down(d, x, y, length=18, color=GREY):
d.add(Line(x, y, x, y - length + 5, strokeColor=color, strokeWidth=1.5))
# arrowhead
d.add(Polygon([x-4, y-length+7, x+4, y-length+7, x, y-length],
fillColor=color, strokeColor=color, strokeWidth=0.5))
def arrow_right(d, x, y, length=30, color=GREY):
d.add(Line(x, y, x + length - 5, y, strokeColor=color, strokeWidth=1.5))
d.add(Polygon([x+length-7, y-4, x+length-7, y+4, x+length, y],
fillColor=color, strokeColor=color, strokeWidth=0.5))
def make_diamond(d, cx, cy, w, h, text, bg=GOLD, fg=WHITE, font_size=7.5):
hw, hh = w/2, h/2
pts = [cx, cy+hh, cx+hw, cy, cx, cy-hh, cx-hw, cy]
d.add(Polygon(pts, fillColor=bg, strokeColor=GREY, strokeWidth=1))
lines = text.split('\n')
line_h = font_size + 1.5
start_y = cy + (len(lines)-1)*line_h/2
for line in lines:
d.add(String(cx, start_y, line, fontName="Helvetica-Bold",
fontSize=font_size, fillColor=fg, textAnchor="middle"))
start_y -= line_h
# ─── FLOWCHART: IMPORT LICENSING ──────────────────────────────────────────────
def import_flowchart():
dw, dh = 480, 340
d = Drawing(dw, dh)
d.add(Rect(0, 0, dw, dh, fillColor=LTBLUE, strokeColor=BLUE, strokeWidth=0.5))
# Title
d.add(String(dw/2, dh-16, "IMPORT LICENSING FLOWCHART (Sec 10 & Ch III)",
fontName="Helvetica-Bold", fontSize=9, fillColor=NAVY, textAnchor="middle"))
# Start
make_box(d, dw/2-55, dh-50, 110, 22, "INTENDING IMPORTER", NAVY, WHITE, 8)
arrow_down(d, dw/2, dh-50, 18)
# Diamond 1
make_diamond(d, dw/2, dh-100, 160, 36,
"Drug in Sec 10\nprohibited list?", GOLD, WHITE, 7.5)
# YES → PROHIBITED
d.add(Line(dw/2+80, dh-100, dw/2+155, dh-100, strokeColor=RED, strokeWidth=1.5))
d.add(Polygon([dw/2+153, dh-104, dw/2+153, dh-96, dw/2+160, dh-100],
fillColor=RED, strokeColor=RED))
make_box(d, dw/2+160, dh-112, 100, 24, "IMPORT\nPROHIBITED", RED, WHITE, 8)
d.add(String(dw/2+110, dh-97, "YES", fontName="Helvetica-Bold", fontSize=7, fillColor=RED))
# NO arrow down
arrow_down(d, dw/2, dh-118, 20)
d.add(String(dw/2+4, dh-124, "NO", fontName="Helvetica-Bold", fontSize=7, fillColor=GREEN))
# Licences box
lic_y = dh - 180
make_box(d, 60, lic_y, 360, 52,
"OBTAIN IMPORT LICENCE from CDSCO (Central)\n"
"Form 10 → Regular import | Form 11 → Test/Analysis\n"
"Form 8 → New Drug import (+ Schedule Y data)",
TEAL, WHITE, 8)
arrow_down(d, dw/2, lic_y, 18)
# Special exceptions
exc_y = lic_y - 65
make_box(d, 60, exc_y, 360, 52,
"SPECIAL EXCEPTIONS (Rules 33, 33-A, 136)\n"
"Rule 33 : Small qty for Test/Analysis (Form 11)\n"
"Rule 33-A : New drug for life-threatening disease\n"
"Rule 136 : Cosmetics for personal use (baggage)",
PURPLE, WHITE, 8)
arrow_down(d, dw/2, exc_y, 18)
# Labelling
label_y = exc_y - 38
make_box(d, 100, label_y, 280, 24,
"Labelling: Parts IX, X, XII compliance\n(Name, Manufacturer, Expiry, Country of Origin)",
BLUE, WHITE, 8)
arrow_down(d, dw/2, label_y, 18)
# Final
make_box(d, dw/2-70, label_y-40, 140, 24,
"CUSTOMS CLEARANCE\n(Sec 11 - Sea Customs Act 1878)",
GREEN, WHITE, 8)
return d
# ─── FLOWCHART: SECTION 18 MANUFACTURE ───────────────────────────────────────
def manufacture_flowchart():
dw, dh = 480, 380
d = Drawing(dw, dh)
d.add(Rect(0, 0, dw, dh, fillColor=LTGREEN, strokeColor=TEAL, strokeWidth=0.5))
d.add(String(dw/2, dh-16, "SECTION 18 - MANUFACTURE PROHIBITION FLOWCHART",
fontName="Helvetica-Bold", fontSize=9, fillColor=TEAL, textAnchor="middle"))
make_box(d, dw/2-80, dh-50, 160, 22, "WANT TO MANUFACTURE A DRUG FOR SALE?", NAVY, WHITE, 7.5)
arrow_down(d, dw/2, dh-50, 18)
# Diamond: New Drug?
make_diamond(d, dw/2, dh-105, 170, 38, "New Drug\n(Rule 122E)?", ORANGE, WHITE, 7.5)
# YES
d.add(Line(dw/2+85, dh-105, dw/2+150, dh-105, strokeColor=ORANGE, strokeWidth=1.5))
d.add(Polygon([dw/2+148, dh-109, dw/2+148, dh-101, dw/2+155, dh-105],
fillColor=ORANGE, strokeColor=ORANGE))
make_box(d, dw/2+155, dh-119, 110, 28,
"CDSCO Approval\n+ Schedule Y\n+ Form 44", ORANGE, WHITE, 7.5)
d.add(String(dw/2+112, dh-102, "YES", fontName="Helvetica-Bold", fontSize=7, fillColor=ORANGE))
arrow_down(d, dw/2, dh-124, 18)
d.add(String(dw/2+4, dh-130, "NO", fontName="Helvetica-Bold", fontSize=7, fillColor=GREEN))
# Diamond: Standard quality?
make_diamond(d, dw/2, dh-180, 180, 38, "Standard Quality?\n(First/Second Schedule)", GOLD, WHITE, 7.5)
d.add(Line(dw/2+90, dh-180, dw/2+155, dh-180, strokeColor=RED, strokeWidth=1.5))
d.add(Polygon([dw/2+153, dh-184, dw/2+153, dh-176, dw/2+160, dh-180],
fillColor=RED, strokeColor=RED))
make_box(d, dw/2+158, dh-192, 100, 24, "PROHIBITED\nSec 18(a)(i)", RED, WHITE, 8)
d.add(String(dw/2+115, dh-177, "NO", fontName="Helvetica-Bold", fontSize=7, fillColor=RED))
arrow_down(d, dw/2, dh-199, 16)
d.add(String(dw/2+4, dh-205, "YES", fontName="Helvetica-Bold", fontSize=7, fillColor=GREEN))
# Apply licence
lic_y = dh - 262
make_box(d, 50, lic_y, 380, 40,
"Apply for Mfg Licence → State Licensing Authority (SLA)\n"
"Form 24 | Premises Inspection | Schedule M (GMP)",
TEAL, WHITE, 8)
arrow_down(d, dw/2, lic_y, 18)
# Licence granted
lg_y = lic_y - 46
make_box(d, 130, lg_y, 220, 22, "LICENCE GRANTED → Form 25", GREEN, WHITE, 8)
arrow_down(d, dw/2, lg_y, 18)
# Ongoing
og_y = lg_y - 62
make_box(d, 50, og_y, 380, 50,
"ONGOING COMPLIANCE\n"
"Schedule M (GMP) | QP on site | BMR records\n"
"Quality testing | Annual returns | Sch U records",
BLUE, WHITE, 8)
arrow_down(d, dw/2, og_y, 16)
make_box(d, dw/2-70, og_y-36, 140, 22, "MANUFACTURE PERMITTED", GREEN, WHITE, 8)
return d
# ─── FLOWCHART: SPECIAL LICENCES ─────────────────────────────────────────────
def special_licence_flowchart():
dw, dh = 480, 270
d = Drawing(dw, dh)
d.add(Rect(0, 0, dw, dh, fillColor=LTPURPLE, strokeColor=PURPLE, strokeWidth=0.5))
d.add(String(dw/2, dh-16, "FOUR SPECIAL LICENCE TYPES [TeNo-Lo-Re]",
fontName="Helvetica-Bold", fontSize=9, fillColor=PURPLE, textAnchor="middle"))
top_y = dh - 50
make_box(d, dw/2-75, top_y, 150, 22, "SPECIAL MANUFACTURE NEED?", NAVY, WHITE, 8)
# Four branches
box_y = top_y - 100
positions = [30, 140, 260, 368]
labels = [
"TEST/ANALYSIS\nForm 11\nSmall qty only\nInspector access",
"NEW DRUG\nForm 44\nCDSCO Central\nSchedule Y data",
"LOAN LICENCE\nForm 25A\nOwn formula\nBorrow premises",
"REPACKING\nForm 25B\nOwn premises\nBulk → repack"
]
colors_list = [TEAL, ORANGE, BLUE, PURPLE]
short = ["Te", "No", "Lo", "Re"]
for i, (px, label, clr, sh) in enumerate(zip(positions, labels, colors_list, short)):
# Line from centre
d.add(Line(dw/2, top_y, px+50, top_y - 50, strokeColor=clr, strokeWidth=1.2,
strokeDashArray=[3,2]))
make_box(d, px, box_y, 100, 68, label, clr, WHITE, 7.5)
# Badge
d.add(Rect(px+35, box_y+60, 30, 14, fillColor=GOLD, strokeColor=GOLD, rx=3, ry=3))
d.add(String(px+50, box_y+63, sh, fontName="Helvetica-Bold",
fontSize=9, fillColor=WHITE, textAnchor="middle"))
# Note
d.add(String(dw/2, 18,
"Loan (25A): if licensor's Form 25 cancelled → 25A auto-cancelled",
fontName="Helvetica-Oblique", fontSize=7.5, fillColor=RED, textAnchor="middle"))
return d
# ─── FLOWCHART: SECTION 27 PENALTY LADDER ────────────────────────────────────
def penalty_ladder_flowchart():
dw, dh = 480, 310
d = Drawing(dw, dh)
d.add(Rect(0, 0, dw, dh, fillColor=LTRED, strokeColor=RED, strokeWidth=0.5))
d.add(String(dw/2, dh-16, "SECTION 27 PENALTY LADDER [3-7-10-LIFE]",
fontName="Helvetica-Bold", fontSize=9.5, fillColor=RED, textAnchor="middle"))
rungs = [
(dh-58, LTGREY, GREY, "Sec 27(d) Other contraventions (labelling/licence condition)\n"
"Up to 1 Year | Fine ≥ ₹20,000"),
(dh-118, LTORANGE, ORANGE,"Sec 27(c) Adulterated drug — NOT causing death\n"
"1 to 3 Years | Fine ≥ ₹50,000"),
(dh-178, LTRED, RED, "Sec 27(b) Spurious drug — NOT causing death/grievous hurt\n"
"NOT < 7 Years, up to LIFE | Fine ≥ ₹3 lakh or 3× value"),
(dh-248, colors.HexColor("#B71C1C"), WHITE,
"Sec 27(a) Adulterated/Spurious → CAUSES DEATH / GRIEVOUS HURT\n"
"NOT < 10 Years, up to LIFE | Fine ≥ ₹10 lakh or 3× value"),
]
for i, (y, bg, fg, text) in enumerate(rungs):
# Rung number badge
badge_c = [GREY, ORANGE, RED, colors.HexColor("#7B0000")][i]
d.add(Rect(20, y, 30, 48, fillColor=badge_c, strokeColor=badge_c, rx=3, ry=3))
d.add(String(35, y+20, str(i+1), fontName="Helvetica-Bold",
fontSize=18, fillColor=WHITE, textAnchor="middle"))
# Main box
d.add(Rect(58, y, dw-78, 48, fillColor=bg, strokeColor=badge_c,
strokeWidth=1.2, rx=4, ry=4))
lines = text.split('\n')
fy = y + 30
for li, line in enumerate(lines):
fn = "Helvetica-Bold" if li == 0 else "Helvetica"
fc = fg if bg != LTGREY else GREY
d.add(String(68, fy, line, fontName=fn, fontSize=8, fillColor=fc))
fy -= 14
# Arrow between rungs
if i < len(rungs)-1:
next_y = rungs[i+1][0]
d.add(Line(dw/2, y, dw/2, next_y+48, strokeColor=colors.HexColor("#7B0000"),
strokeWidth=1.2))
return d
# ─── FLOWCHART: MANUFACTURE TO SALE ──────────────────────────────────────────
def mfg_to_sale_flowchart():
dw, dh = 480, 420
d = Drawing(dw, dh)
d.add(Rect(0, 0, dw, dh, fillColor=LTGOLD, strokeColor=GOLD, strokeWidth=0.5))
d.add(String(dw/2, dh-16,
"CONSOLIDATED MANUFACTURE → SALE COMPLIANCE [MASt-P-New]",
fontName="Helvetica-Bold", fontSize=9, fillColor=NAVY, textAnchor="middle"))
stages = [
(dh-50, "A. PRE-MANUFACTURE", "New Drug? → CDSCO + Sch Y + Form 44\nStandard Drug? → Proceed", NAVY),
(dh-108, "B. LICENSING", "SLA Form 24 → Inspection → Sch M GMP\nLicence Form 25 Granted", TEAL),
(dh-166, "C. MANUFACTURE", "GMP premises | QP present | BMR records\nIn-process QC | Batch quarantine", BLUE),
(dh-224, "D. QUALITY CONTROL", "Test vs First/Second Schedule | Govt Analyst\nRef samples: 3 yrs / 3 months post-expiry", PURPLE),
(dh-282, "E. LABELLING", "Sch G: CAUTION label | Sch H: Rx symbol\nSch H1: RED STRIP | Sch X: Special Rx", PINK),
(dh-340, "F. DISTRIBUTION", "Wholesale Lic Form 20/21 | Cold chain (Sch C)\nInvoice & stock register", ORANGE),
(dh-390, "G. RETAIL SALE", "Retail Lic Form 20 | Registered Pharmacist\nPrescription register for H/H1/X drugs", GREEN),
]
for i, (y, stage, detail, clr) in enumerate(stages):
# Stage tag
d.add(Rect(10, y, 120, 46, fillColor=clr, strokeColor=clr, rx=4, ry=4))
d.add(String(70, y+24, stage.split('.')[0] + '.', fontName="Helvetica-Bold",
fontSize=7.5, fillColor=WHITE, textAnchor="middle"))
d.add(String(70, y+13, stage.split('. ', 1)[1], fontName="Helvetica-Bold",
fontSize=7.5, fillColor=WHITE, textAnchor="middle"))
# Detail box
d.add(Rect(138, y, dw-150, 46,
fillColor=WHITE, strokeColor=clr, strokeWidth=1, rx=4, ry=4))
lines2 = detail.split('\n')
ty = y + 28
for line in lines2:
d.add(String(148, ty, line, fontName="Helvetica", fontSize=7.8, fillColor=GREY))
ty -= 14
# Down arrow
if i < len(stages)-1:
ay = y - 2
d.add(Line(dw/2, ay, dw/2, ay-8, strokeColor=GREY, strokeWidth=1.5))
d.add(Polygon([dw/2-4, ay-6, dw/2+4, ay-6, dw/2, ay-12],
fillColor=GREY, strokeColor=GREY))
return d
# ─── DOCUMENT BUILDER ─────────────────────────────────────────────────────────
def build_pdf(path):
doc = SimpleDocTemplate(
path, pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2.2*cm, bottomMargin=2.2*cm,
title="Drugs & Cosmetics Act 1940 – Student Handbook",
author="Professor's Notes"
)
story = []
PW = doc.width # printable width
# ══════════════════════ COVER PAGE ════════════════════════════════════════
class CoverPage(Flowable):
def wrap(self, aw, ah): return aw, ah
def draw(self):
c = self.canv
pw, ph = A4
# Gradient background simulation (layered rectangles)
for i in range(80):
frac = i / 80
r = 0.10 + frac * 0.05
g = 0.14 + frac * 0.02
b = 0.49 - frac * 0.15
c.setFillColorRGB(r, g, b)
c.rect(0, ph * (1 - (i+1)/80), pw, ph/80 + 1, fill=1, stroke=0)
# Decorative circles
c.setFillColorRGB(1,1,1,0.06)
c.circle(pw*0.85, ph*0.78, 90, fill=1, stroke=0)
c.circle(pw*0.12, ph*0.22, 60, fill=1, stroke=0)
c.setFillColorRGB(1,1,1,0.04)
c.circle(pw*0.5, ph*0.5, 160, fill=1, stroke=0)
# Top accent bar
c.setFillColor(colors.HexColor("#FFD600"))
c.rect(0, ph-8, pw, 8, fill=1, stroke=0)
# Main title
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 30)
c.drawCentredString(pw/2, ph*0.72, "DRUGS & COSMETICS")
c.setFont("Helvetica-Bold", 30)
c.drawCentredString(pw/2, ph*0.65, "ACT, 1940")
# Subtitle
c.setFillColor(colors.HexColor("#FFD600"))
c.setFont("Helvetica-Bold", 15)
c.drawCentredString(pw/2, ph*0.58, "Complete Student Handbook")
# Divider
c.setStrokeColor(colors.HexColor("#FFD600"))
c.setLineWidth(2)
c.line(pw*0.2, ph*0.545, pw*0.8, ph*0.545)
# Feature pills
features = [
"Schedules & Rule Schedules",
"Import | Manufacture | Sale",
"Penalty Ladders (Sec 13 & 27)",
"Flowcharts & Mnemonics",
"Exam Traps & High-Yield Points"
]
c.setFillColor(colors.HexColor("#E3F2FD"))
c.setFont("Helvetica", 11)
for j, feat in enumerate(features):
c.drawCentredString(pw/2, ph*0.49 - j*0.055*ph, "◆ " + feat)
# Bottom bar
c.setFillColor(colors.HexColor("#FFD600"))
c.rect(0, 0, pw, 48, fill=1, stroke=0)
c.setFillColor(NAVY)
c.setFont("Helvetica-Bold", 11)
c.drawCentredString(pw/2, 28, "Based on Bare Act | CDSCO Official Text | Forensic Medicine 36e (2026)")
c.setFont("Helvetica", 9)
c.drawCentredString(pw/2, 12, "For Educational Use Only")
story.append(CoverPage())
story.append(PageBreak())
# ══════════════════════ TABLE OF CONTENTS ═════════════════════════════════
story.append(ColorBanner("TABLE OF CONTENTS", NAVY, WHITE, 24, 14))
story.append(Spacer(1, 8))
toc_data = [
("PART 1", "The Schedules — First, Second & Rule Schedules", "3"),
("PART 2", "Import of Drugs — Section 10, Licensing, Section 13 Penalties", "5"),
("PART 3", "Manufacture of Drugs — Section 18, Schedule M, Special Licences", "8"),
("PART 4", "Section 27 Penalty Ladder (3→7→10→Life)", "12"),
("PART 5", "Consolidated Manufacture-to-Sale Compliance Flowchart", "14"),
("PART 6", "Master Mnemonics Cheatsheet", "15"),
("PART 7", "Exam Traps & High-Yield Points", "16"),
]
toc_table = Table(
[["Part", "Topic", "Pg"]] + toc_data,
colWidths=[1.5*cm, PW - 3.5*cm, 1.5*cm]
)
toc_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), NAVY),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 10),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, LTBLUE]),
('GRID', (0,0), (-1,-1), 0.3, BLUE),
('VALIGN',(0,0),(-1,-1),'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING',(0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 6),
]))
story.append(toc_table)
story.append(PageBreak())
# ══════════════════════ PART 1: SCHEDULES ═════════════════════════════════
story.append(ColorBanner("PART 1 | THE SCHEDULES", NAVY, WHITE, 26, 15))
story.append(Spacer(1, 6))
story.append(ColorBanner("FIRST SCHEDULE — Books of Standards (Section 3(b))", BLUE, WHITE, 20, 11))
story.append(Spacer(1, 5))
story.append(Paragraph(
"The First Schedule lists the official pharmacopoeias and formularies whose standards define 'standard quality' under the Act. "
"A drug must conform to the standard in the applicable book listed here.",
body))
story.append(Spacer(1, 4))
first_sch = [
["Reference Text", "Applicability"],
["Pharmacopoeia of India (IP)", "Primary Indian standard — applies to all IP-listed drugs"],
["British Pharmacopoeia (BP)", "Applies to drugs described therein"],
["International Pharmacopoeia (WHO)", "WHO standard for internationally traded drugs"],
["Extra Pharmacopoeia (Martindale)", "Reference for drugs not in other pharmacopoeias"],
["United States Pharmacopeia (USP)", "Applicable where specified"],
["British Pharmaceutical Codex (BPC)", "Additional standard for formulations"],
["British Veterinary Codex", "Veterinary drugs"],
["Ayurvedic Pharmacopoeia of India", "AYUSH Ayurvedic drugs"],
["Siddha Vaidya Thirattu / Unani Pharmacopoeia", "AYUSH Siddha & Unani system drugs"],
]
story.append(colored_table(first_sch, [PW*0.42, PW*0.58], BLUE, WHITE, LTBLUE, BLUE))
story.append(Spacer(1, 5))
story.append(Paragraph("Mnemonic: <b>I BIG BBA US</b> = IP, BP, International, German, British Vet Codex, British Pharma Codex, Ayurvedic/Siddha/Unani, USP", mnemonic))
story.append(Spacer(1, 8))
story.append(ColorBanner("SECOND SCHEDULE — Standards of Quality", TEAL, WHITE, 20, 11))
story.append(Spacer(1, 5))
story.append(Paragraph(
"Lists specific standards (purity, potency, test methods) for drugs manufactured or imported. "
"Any drug whose standard appears here must fully comply — failing to do so makes it 'not of standard quality' under Section 16. "
"A fixed-dose combination of a Second Schedule drug with an Ayurvedic drug is explicitly prohibited by Section 10A notifications.",
body))
story.append(Spacer(1, 8))
# Rule Schedules table
story.append(ColorBanner("HIGH-YIELD RULE SCHEDULES — Drugs & Cosmetics Rules 1945", PURPLE, WHITE, 20, 11))
story.append(Spacer(1, 5))
story.append(Paragraph("Mnemonic: <b>C Gets High — H1 too, Just Keep Making Perfectly True eXtra Years</b>", mnemonic))
story.append(Spacer(1, 5))
sch_data = [
["Sch", "Contents", "Key Requirement"],
["C", "Biological & special products\n(vaccines, sera, toxoids, hormones,\nantibiotic injectables)",
"Enhanced storage/cold chain\nManufacture under stricter GMP\nCentral Licensing Authority (not SLA)"],
["C1", "Large-volume parenterals (LVP)", "Separate GMP + separate manufacturing"],
["G", "~65 drugs: antihistamines, insulin,\nbleomycin, aminopterine, cytotoxics",
"Label MUST carry:\n'CAUTION — For use only under\nmedical supervision'"],
["H", "Prescription-only drugs (antibiotics,\nsteroids, antihypertensives, etc.)",
"Only on RMP prescription\nPrescription register mandatory\n'Rx' symbol on label"],
["H1", "High-risk Rx drugs: 3rd/4th gen\ncephalosporins, carbapenems,\nfluoroquinolones, anti-TB, antifungals",
"RED STRIP on label\nPrescription RETAINED 2 years\nNo repeat Rx without fresh prescription"],
["J", "54 diseases for which no drug may\nclaim to be a cure (cancer, AIDS,\ndiabetes, etc.)",
"Any cure claim = misbranding\nProhibited advertising"],
["K", "Drugs exempt from Ch IV/IVA in\nsome states (AYUSH, homeopathy)",
"Limited applicability by state notification"],
["M", "GMP standards for premises, plant,\nmachinery, personnel, documentation",
"Mandatory for all licensed mfrs\n= Indian GMP standard"],
["P", "Life period of drugs — storage\nperiod/shelf-life guidelines",
"Governs expiry dating on labels"],
["T", "Standards for surgical dressings,\nbandages, orthopaedic implants",
"Quality standards for medical devices"],
["X", "Habit-forming/psychotropic drugs:\nmorphine, pethidine, fentanyl,\ncodeine formulations",
"Strict licence (Form 20-A)\nSpecial Rx mandatory\nRecords kept 2 years\nNo advertisement"],
["Y", "Requirements for clinical trials\n(data to be submitted for new drugs)",
"Preclinical + Phase I-III clinical\ndata package for CDSCO approval"],
]
sch_colors = {
1: (LTBLUE, BLUE), 2: (LTBLUE, BLUE),
3: (LTGOLD, GOLD), 4: (LTPINK, PINK),
5: (LTRED, RED), 6: (LTTEAL, TEAL),
7: (LTGREY, GREY), 8: (LTTEAL, TEAL),
9: (LTGOLD, GOLD), 10: (LTBLUE, BLUE),
11: (LTRED, RED), 12: (LTPURPLE, PURPLE),
}
t = Table(sch_data, colWidths=[1.0*cm, PW*0.42, PW*0.43])
ts_style = [
('BACKGROUND', (0,0), (-1,0), PURPLE),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 9),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,1), (-1,-1), 8),
('GRID', (0,0), (-1,-1), 0.4, PURPLE),
('VALIGN',(0,0),(-1,-1),'MIDDLE'),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING',(0,0), (-1,-1), 4),
]
for row_i, (bg, _) in sch_colors.items():
ts_style.append(('BACKGROUND', (0, row_i), (-1, row_i), bg))
ts_style.append(('FONTNAME', (0, row_i), (0, row_i), 'Helvetica-Bold'))
ts_style.append(('TEXTCOLOR', (0, row_i), (0, row_i), _))
ts_style.append(('FONTSIZE', (0, row_i), (0, row_i), 12))
ts_style.append(('ALIGN', (0, row_i), (0, row_i), 'CENTER'))
t.setStyle(TableStyle(ts_style))
story.append(t)
story.append(PageBreak())
# ══════════════════════ PART 2: IMPORT ════════════════════════════════════
story.append(ColorBanner("PART 2 | IMPORT OF DRUGS", TEAL, WHITE, 26, 15))
story.append(Spacer(1, 6))
story.append(ColorBanner("SECTION 10 — Prohibited Drug Imports", TEAL, WHITE, 20, 11))
story.append(Spacer(1, 5))
story.append(Paragraph("Mnemonic: <b>MASque</b> = Misbranded, Adulterated, Spurious, quality-substandard, extra-prohibited", mnemonic))
story.append(Spacer(1, 5))
sec10_data = [
["Clause", "What is Prohibited"],
["10(a)", "Not of standard quality (below First/Second Schedule standard)"],
["10(b)", "Misbranded (Section 9 definition)"],
["10(c)", "Adulterated (Section 9A definition)"],
["10(d)", "Spurious (Section 9B definition)"],
["10(ee)", "Cosmetic tested on animals [Post-2014 Fifth Amendment Rules]"],
["10(f)", "Without a valid import licence (Form 10)"],
["10A", "Any drug notified by Central Govt as dangerous or lacking\ntherapeutic value (e.g. Nialamide, Practolol, Amidopyrin,\nPhenacetin, Methaqualone, Analgin combinations)"],
]
story.append(colored_table(sec10_data, [1.8*cm, PW-1.8*cm], TEAL, WHITE, LTTEAL, TEAL))
story.append(Spacer(1, 8))
story.append(ColorBanner("IMPORT LICENSING FLOWCHART", BLUE, WHITE, 18, 10))
story.append(Spacer(1, 5))
fc1 = import_flowchart()
fc1.width = PW
story.append(fc1)
story.append(Spacer(1, 8))
story.append(ColorBanner("SECTION 13 — PENALTY TABLE (Verified Against Bare Act)", RED, WHITE, 20, 11))
story.append(Spacer(1, 5))
story.append(Paragraph(
"<b>NOTE:</b> Section 13 fine figures are LOW (₹500-₹5,000) — this is a classic exam trap compared to Section 27 lakhs-level fines. "
"Section 13 figures have NOT been updated by recent amendments.",
trap_style))
story.append(Spacer(1, 5))
sec13_data = [
["Clause", "Offence", "Imprisonment", "Fine"],
["13(1)(a)", "Import of adulterated/spurious drug\n(Sec 9A/9B) OR animal-tested cosmetic\n(Sec 10, cl. ee)", "Up to 3 YEARS", "Up to ₹5,000"],
["13(1)(b)", "Import of any other prohibited drug/\ncosmetic (Sec 10)", "Up to 6 MONTHS", "Up to ₹500\nOR both"],
["13(1)(c)", "Import in contravention of\nSection 10A notification", "Up to 3 YEARS", "Up to ₹5,000\nOR both"],
["13(2)\nsubsequent", "Repeat conviction under 13(1)(a)", "Up to 7 YEARS", "Up to ₹5,000"],
]
story.append(penalty_table(sec13_data, [1.8*cm, PW*0.40, PW*0.25, PW*0.22]))
story.append(PageBreak())
# ══════════════════════ PART 3: MANUFACTURE ═══════════════════════════════
story.append(ColorBanner("PART 3 | MANUFACTURE OF DRUGS", BLUE, WHITE, 26, 15))
story.append(Spacer(1, 6))
story.append(ColorBanner("SECTION 18 — Prohibitions", BLUE, WHITE, 20, 11))
story.append(Spacer(1, 5))
story.append(Paragraph("Mnemonic: <b>No MSA-P-N-L-C</b> = No Misbranded, Spurious, Adulterated, Patent/Proprietary (unlabelled), New drug (unapproved), Licence (non-compliance), Contraband", mnemonic))
story.append(Spacer(1, 5))
sec18_data = [
["Sub-section", "Prohibition"],
["18(a)(i)", "Drug not of standard quality / misbranded / adulterated / spurious"],
["18(a)(ii)", "Cosmetic not of standard quality / misbranded / adulterated / spurious"],
["18(a)(iii)", "Patent/proprietary medicine without displaying true formula or active ingredient list on label"],
["18(a)(iv)", "Drug without a valid licence under Section 18(c)"],
["18(a)(v)", "Drug in contravention of any condition of the licence"],
["18(a)(vi)", "New Drug (Rule 122E) without CDSCO approval"],
["18(a)(vii)", "Any drug in violation of notified restriction (Section 26A/26B)"],
["18(b)", "Advertising that any drug cures a Schedule J disease"],
["18(c)", "Manufacture without a licence from the Licensing Authority (Rule 68/69)"],
]
story.append(colored_table(sec18_data, [2.6*cm, PW-2.6*cm], BLUE, WHITE, LTBLUE, BLUE))
story.append(Spacer(1, 5))
story.append(Paragraph(
"<b>Proviso:</b> Manufacture of small quantities for examination, test or analysis is EXEMPT from Sec 18 restrictions "
"(but still requires a test/analysis licence under Rule 68).",
note_style))
story.append(Spacer(1, 8))
story.append(ColorBanner("SECTION 18 MANUFACTURE PROHIBITION FLOWCHART", BLUE, WHITE, 18, 10))
story.append(Spacer(1, 5))
fc2 = manufacture_flowchart()
fc2.width = PW
story.append(fc2)
story.append(Spacer(1, 8))
story.append(ColorBanner("SCHEDULE M — GMP Requirements", TEAL, WHITE, 20, 11))
story.append(Spacer(1, 5))
gmp_data = [
["GMP Element", "Key Requirements"],
["Buildings & Premises", "Adequate space | Clean room classifications\nSegregated areas: quarantine / sampling / mfg / dispensing / FG"],
["Equipment", "Validated & calibrated | Stainless steel where required | Cleaned & logged"],
["Personnel", "Qualified Person (QP) mandatory | Training records | Health surveillance"],
["Sanitation", "SOPs for cleaning | Pest control | Gowning procedures"],
["Documentation", "Batch Manufacturing Records (BMR) | SOPs | Batch Packing Records"],
["Quality Control", "In-process testing | Release testing\nRef samples: 3 yrs (no expiry) | 3 months post-expiry"],
["Self-Inspection", "Periodic internal audits | Documented CAPA"],
["Complaints & Recalls", "Written procedures mandatory | Traceability to batch"],
]
story.append(colored_table(gmp_data, [PW*0.30, PW*0.70], TEAL, WHITE, LTTEAL, TEAL))
story.append(Spacer(1, 8))
story.append(ColorBanner("FOUR SPECIAL LICENCE TYPES [TeNo-Lo-Re]", PURPLE, WHITE, 20, 11))
story.append(Spacer(1, 5))
story.append(Paragraph("Mnemonic: <b>TeNo-Lo-Re</b> = Test/analysis, New drug, Loan licence, Repacking licence", mnemonic))
story.append(Spacer(1, 5))
lic4_data = [
["Licence", "Form", "Who Applies", "Key Features"],
["Test/Analysis\nLicence", "Form 11\n(import)\nForm 24 cat.\n(mfg)", "Research labs\nAnalytical labs",
"Small quantities only\nNon-commercial use\nTest facility specified in licence\nInspector access MANDATORY"],
["New Drug\nLicence", "Form 44", "Manufacturer of\na New Drug\n(Rule 122E)", "Phase I-III clinical trial data\n(Schedule Y) compulsory\nCDSCO Central approval ONLY\n(NOT State SLA)"],
["Loan Licence", "Form 25A\n(Rule 69A)", "Company with\nformula but no\nown plant",
"Uses licensor's premises + equipment\nLicensor must hold valid Form 25\nAuto-cancelled if licensor's\nForm 25 cancelled/suspended"],
["Repacking\nLicence", "Form 25B\n(Rule 74A)", "Company buying\nbulk drug for\nrepackaging",
"Qualified competent person\nmust supervise at ALL times\nOwn testing facility required\nNo alteration of drug substance"],
]
t4 = Table(lic4_data, colWidths=[2.3*cm, 1.8*cm, 2.5*cm, PW-6.6*cm])
t4.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), PURPLE),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 9),
('BACKGROUND', (0,1), (-1,1), LTTEAL),
('BACKGROUND', (0,2), (-1,2), LTORANGE),
('BACKGROUND', (0,3), (-1,3), LTBLUE),
('BACKGROUND', (0,4), (-1,4), LTPURPLE),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,1), (-1,-1), 8),
('GRID', (0,0), (-1,-1), 0.4, PURPLE),
('VALIGN',(0,0),(-1,-1),'TOP'),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING',(0,0), (-1,-1), 5),
]))
story.append(t4)
story.append(Spacer(1, 8))
story.append(ColorBanner("SPECIAL LICENCE COMPARISON FLOWCHART", PURPLE, WHITE, 18, 10))
story.append(Spacer(1, 5))
fc3 = special_licence_flowchart()
fc3.width = PW
story.append(fc3)
story.append(PageBreak())
# ══════════════════════ PART 4: SECTION 27 ════════════════════════════════
story.append(ColorBanner("PART 4 | SECTION 27 PENALTY LADDER", RED, WHITE, 26, 15))
story.append(Spacer(1, 6))
story.append(Paragraph("Mnemonic: <b>3-7-10-LIFE</b> — remember the MINIMUM sentences!", mnemonic))
story.append(Spacer(1, 8))
story.append(ColorBanner("SECTION 27 PENALTY LADDER FLOWCHART", RED, WHITE, 18, 10))
story.append(Spacer(1, 5))
fc4 = penalty_ladder_flowchart()
fc4.width = PW
story.append(fc4)
story.append(Spacer(1, 10))
story.append(ColorBanner("SECTION 27 — Detailed Penalty Table (Verified: CDSCO + India Code)", RED, WHITE, 18, 10))
story.append(Spacer(1, 6))
s27_data = [
["Clause", "Offence", "Min Imprisonment", "Max Imprisonment", "Fine"],
["27(d)", "Any other contravention\n(labelling error, licence\ncondition breach)", "—", "1 Year",
"≥ ₹20,000\n(Court may reduce\non recorded reasons)"],
["27(c)", "Adulterated drug (Sec 17A)\nNOT causing death\nor grievous hurt", "1 Year", "3 Years",
"≥ ₹50,000"],
["27(b)", "Spurious drug (Sec 17B)\nNOT causing death\nor grievous hurt",
"7 Years\n(Proviso: Court may\nimpose < 7 yrs)", "LIFE",
"≥ ₹3 lakh\nOR 3× drug value\n(whichever more)"],
["27(a)\n★ HIGHEST ★", "Adulterated/Spurious drug\nWHICH CAUSES or IS\nLIKELY TO CAUSE DEATH\nor GRIEVOUS HARM",
"10 Years\n(Proviso: Court may\nimpose < 10 yrs)", "LIFE",
"≥ ₹10 lakh\nOR 3× drug value\n(whichever more)"],
]
ts27 = TableStyle([
('BACKGROUND', (0,0), (-1,0), RED),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 8.5),
('BACKGROUND', (0,1), (-1,1), LTGREY),
('BACKGROUND', (0,2), (-1,2), LTORANGE),
('BACKGROUND', (0,3), (-1,3), LTRED),
('BACKGROUND', (0,4), (-1,4), colors.HexColor("#FFCDD2")),
('FONTNAME', (0,4), (-1,4), 'Helvetica-Bold'),
('TEXTCOLOR', (0,4), (-1,4), RED),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,1), (-1,-1), 8),
('GRID', (0,0), (-1,-1), 0.4, RED),
('VALIGN',(0,0),(-1,-1),'MIDDLE'),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING',(0,0), (-1,-1), 5),
])
t27 = Table(s27_data, colWidths=[1.8*cm, PW*0.33, PW*0.20, PW*0.20, PW*0.22])
t27.setStyle(ts27)
story.append(t27)
story.append(Spacer(1, 8))
story.append(ColorBanner("SECTION 30 — Subsequent Offence Enhancement", RED, WHITE, 18, 10))
story.append(Spacer(1, 5))
s30_data = [
["Previous Conviction", "Enhanced Repeat Punishment"],
["Under Sec 27(b)\n(spurious, no death)", "NOT < 7 yrs, up to 10 Years\n+ Fine ≥ ₹2 lakh"],
["Under Sec 27(c)\n(adulterated, no death)", "NOT < 10 yrs, up to LIFE\n+ Fine ≥ ₹3 lakh"],
["Under Sec 27(d)\n(other contravention)", "NOT < 2 yrs, up to 4 Years\nOR Fine ≥ ₹50,000, or both"],
]
story.append(colored_table(s30_data, [PW*0.45, PW*0.55], RED, WHITE, LTRED, RED))
story.append(PageBreak())
# ══════════════════════ PART 5: MFG TO SALE FLOWCHART ════════════════════
story.append(ColorBanner("PART 5 | CONSOLIDATED MANUFACTURE-TO-SALE FLOWCHART", GOLD, NAVY, 26, 14))
story.append(Spacer(1, 6))
story.append(Paragraph("Mnemonic: <b>MASt-P-New</b> = Manufacture lic | Approved premises | Standard quality | testing | Packaging | New drug approval", mnemonic))
story.append(Spacer(1, 8))
fc5 = mfg_to_sale_flowchart()
fc5.width = PW
story.append(fc5)
story.append(PageBreak())
# ══════════════════════ PART 6: MNEMONICS ═════════════════════════════════
story.append(ColorBanner("PART 6 | MASTER MNEMONICS CHEATSHEET", PURPLE, WHITE, 26, 15))
story.append(Spacer(1, 6))
mnemonics_data = [
["Mnemonic", "Full Form", "Covers"],
["MASque", "Misbranded, Adulterated,\nSpurious, quality-substandard,\nextra-prohibited", "Prohibited drug categories\n(Sec 10 & Sec 18)"],
["MASt-P-New", "Manufacture lic, Approved premises,\nStandard drugs, testing,\nPackaging/labelling, New drug lic",
"Full compliance checklist\nSec 18 onwards"],
["TeNo-Lo-Re", "Test/analysis licence,\nNew drug licence,\nLoan licence,\nRepacking licence",
"4 Special licence types\n(Forms 11/44/25A/25B)"],
["3-7-10-Life", "3 yrs (Sec 13/27c category),\n7 yrs min (Sec 27b spurious),\n10 yrs min (Sec 27a death),\nLife maximum",
"Penalty ladder\nSection 27 + 30"],
["C Gets High\nH1 too", "C=Biological, G=Caution label,\nH=Rx only, H1=Red strip",
"Prescription schedule\nrequirements"],
["J bans K M P T X Y", "J=No-cure claims, K=Exempt,\nM=GMP, P=Shelf life,\nT=Surgical, X=Habit-forming,\nY=Clinical trial data",
"All high-yield Rule Schedules"],
["I BIG BBA US", "IP, BP, International, German,\nBritish Vet, British Pharma Codex,\nAyurvedic/Siddha/Unani, USP",
"First Schedule\nStandard books"],
]
mn_t = Table(mnemonics_data, colWidths=[2.8*cm, PW*0.42, PW*0.38])
mn_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), PURPLE),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 9.5),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('TEXTCOLOR', (0,1), (0,-1), PURPLE),
('FONTSIZE', (0,1), (0,-1), 11),
('FONTNAME', (1,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (1,1), (-1,-1), 8.5),
('ROWBACKGROUNDS', (0,1), (-1,-1), [LTPURPLE, WHITE]),
('GRID', (0,0), (-1,-1), 0.4, PURPLE),
('VALIGN',(0,0),(-1,-1),'MIDDLE'),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING',(0,0), (-1,-1), 6),
]))
story.append(mn_t)
story.append(PageBreak())
# ══════════════════════ PART 7: EXAM TRAPS ════════════════════════════════
story.append(ColorBanner("PART 7 | EXAM TRAPS & HIGH-YIELD POINTS", RED, WHITE, 26, 15))
story.append(Spacer(1, 6))
traps = [
("1. Section 27 vs Section 13 Fines",
"Sec 27 fines = LAKHS (₹10 lakh for death-causing drugs). Sec 13 fines = TINY (₹500-₹5,000). "
"Both are frequently tested side-by-side. The small Section 13 fine amounts have NOT been updated by recent amendments."),
("2. Loan Licence (Form 25A) Auto-Cancellation",
"If the licensor's Form 25 is cancelled or suspended → the loan licensee's Form 25A is AUTOMATICALLY cancelled. "
"No separate notice/procedure needed. (Rule 74B)"),
("3. Schedule H1 = RED STRIP (not Red Box/Cross)",
"H1 requires a RED STRIP across the top of the label. Prescription must be RETAINED by the chemist for 2 years. "
"Cannot be dispensed again without a FRESH prescription. Introduced by 2013 amendment to curb antibiotic resistance."),
("4. New Drug Approval = CDSCO Central Only",
"New Drug (Rule 122E) licence (Form 44) requires Central Government/CDSCO approval — NOT State Licensing Authority. "
"This is a classic MCQ distractor."),
("5. Section 18 Proviso — Test/Analysis Exemption",
"Small quantities manufactured ONLY for examination, test or analysis are EXEMPT from Section 18 prohibitions. "
"BUT a test/analysis licence under Rule 68 is still required."),
("6. Section 27(a) Threshold — 'Likely to Cause'",
"Section 27(a) (10 years to life) applies when a drug IS LIKELY TO CAUSE death or grievous harm — not just when death actually occurs. "
"Prosecution does not need to wait for actual death."),
("7. Cognizable & Non-Bailable Offences",
"Spurious/adulterated drugs that CAUSE DEATH are COGNIZABLE (police can arrest without warrant) and NON-BAILABLE. "
"This is a distinct feature vs. other offences under the Act."),
("8. Schedule C Drugs — Central, Not State, Authority",
"Biological products (Schedule C) are licensed by the CENTRAL Licensing Authority (CDSCO), not the State Licensing Authority, "
"unlike most other allopathic drugs."),
("9. No Advertisement of Sch H / H1 / X",
"Advertisement of Schedule H, H1, or X drugs requires PRIOR SANCTION of the Central Government (Rule 74). "
"This is absolute — no advertisement without this sanction."),
("10. Reference Sample Retention Times",
"3 YEARS from date of manufacture (if NO expiry date on label). "
"3 MONTHS BEYOND EXPIRY DATE (if expiry date is stated on label). "
"Frequently tested in MCQs — do not confuse these two figures."),
("11. Section 10A vs Section 10",
"Section 10 = statutory prohibition of specific drug classes (misbranded, adulterated, spurious, etc.). "
"Section 10A = Central Govt's POWER to prohibit ANY drug by notification (e.g., analgin combinations, phenacetin). "
"Section 10A requires a Gazette notification; Section 10 applies automatically."),
("12. Fixed Dose Combination (FDC) Trap",
"A fixed-dose combination of a Second Schedule drug with an Ayurvedic drug is PROHIBITED under Section 10A notifications — "
"even if both drugs are individually permitted. Examiners love this nuance."),
]
for i, (heading, content) in enumerate(traps):
row_bg = LTRED if i % 2 == 0 else LTORANGE
trap_data = [[heading, content]]
tr = Table(trap_data, colWidths=[PW*0.34, PW*0.66])
tr.setStyle(TableStyle([
('BACKGROUND', (0,0), (0,0), RED if i % 2 == 0 else ORANGE),
('TEXTCOLOR', (0,0), (0,0), WHITE),
('BACKGROUND', (1,0), (1,0), row_bg),
('TEXTCOLOR', (1,0), (1,0), GREY),
('FONTNAME', (0,0), (0,0), 'Helvetica-Bold'),
('FONTNAME', (1,0), (1,0), 'Helvetica'),
('FONTSIZE', (0,0), (-1,0), 8.5),
('VALIGN', (0,0), (-1,0), 'MIDDLE'),
('GRID', (0,0), (-1,-1), 0.3, RED),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING',(0,0), (-1,-1), 5),
]))
story.append(tr)
story.append(Spacer(1, 3))
story.append(Spacer(1, 12))
# Footer disclaimer
story.append(HRFlowable(width=PW, thickness=1, color=NAVY))
story.append(Spacer(1, 4))
story.append(Paragraph(
"Sources: CDSCO Official PDF of Drugs & Cosmetics Act & Rules 2016 | India Code Bare Act (indiacode.nic.in) | "
"Karnataka Drugs Control Dept Penalty Table 2025 | The Essentials of Forensic Medicine & Toxicology 36e (2026) | "
"For Educational Use Only",
footer_sty))
# ─── PAGE NUMBERING ───────────────────────────────────────────────────────
def add_page_decorations(canvas, doc):
canvas.saveState()
pw, ph = A4
# Top bar
canvas.setFillColor(NAVY)
canvas.rect(0, ph-14, pw, 14, fill=1, stroke=0)
canvas.setFillColor(WHITE)
canvas.setFont("Helvetica-Bold", 7)
canvas.drawCentredString(pw/2, ph-10, "Drugs & Cosmetics Act 1940 — Student Handbook")
# Bottom bar
canvas.setFillColor(LTBLUE)
canvas.rect(0, 0, pw, 16, fill=1, stroke=0)
canvas.setFillColor(NAVY)
canvas.setFont("Helvetica", 7.5)
canvas.drawString(2*cm, 5, "For Educational Use Only")
canvas.drawRightString(pw - 2*cm, 5, f"Page {doc.page}")
canvas.restoreState()
doc.build(story, onFirstPage=add_page_decorations, onLaterPages=add_page_decorations)
print(f"PDF generated: {path}")
if __name__ == "__main__":
out = "/home/daytona/workspace/dca-handbook/DCA_1940_Student_Handbook.pdf"
build_pdf(out)
cd /home/daytona/workspace/dca-handbook && python3 generate_handbook.py 2>&1
~/dca-handbook/generate_handbook.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/dca-handbook/generate_handbook.py'
cd /home/daytona/workspace/dca-handbook && python3 generate_handbook.py 2>&1
ls -lh /home/daytona/workspace/dca-handbook/DCA_1940_Student_Handbook.pdf
DCA 1940 Student Handbook
PDF Document · PDF
| Part | Content |
|---|---|
| Cover Page | Full-color gradient cover with gold accent bar |
| Table of Contents | Navy-blue styled TOC with page references |
| Part 1 | First & Second Schedules + all Rule Schedules (C, G, H, H1, J, K, M, P, T, X, Y) — color-coded table with each schedule highlighted individually |
| Part 2 | Section 10 prohibited classes table + Import Licensing Flowchart (with diamond decision nodes, colored boxes, arrows) + Section 13 Penalty Table in red |
| Part 3 | Section 18 Prohibitions table + Manufacture Prohibition Flowchart + Schedule M GMP requirements + Four Special Licence table + TeNo-Lo-Re Flowchart |
| Part 4 | Section 27 Penalty Ladder Flowchart (numbered rungs from grey → orange → red → dark red) + detailed penalty table + Section 30 subsequent offence table |
| Part 5 | Consolidated Manufacture-to-Sale Flowchart (7-stage A through G with colored stage badges) |
| Part 6 | Master Mnemonics Cheatsheet (MASque, MASt-P-New, TeNo-Lo-Re, 3-7-10-Life, etc.) |
| Part 7 | 12 Exam Traps & High-Yield Points in alternating red/orange highlighted rows |