How to write doctors order/advise for fluid correction of SBO patient

Reading File
Finding Sources
Finding Sources
Searching the Web

small bowel obstruction fluid resuscitation doctor orders IV fluid management

Reading File
Reading File
Finding Sources
I now have excellent, detailed textbook content. Let me compile a comprehensive, practical doctor's order sheet.

Doctor's Orders - Fluid Correction for SBO Patient

Below is a structured, ward-ready order set based on authoritative surgical textbooks (Maingot's, Schwartz's, Sabiston's, Mulholland & Greenfield's).

ADMISSION ORDERS - SMALL BOWEL OBSTRUCTION


1. CONDITION & MONITORING

1. Admit to: Surgical Ward / HDU (depending on severity)
2. Diagnosis: Small Bowel Obstruction
3. Condition: Guarded
4. Activity: Bed rest
5. Vital signs: Every 1-2 hours (BP, HR, RR, SpO2, Temperature)
6. Strict input/output chart - hourly urine output monitoring
7. Insert urinary catheter (Foley) - target urine output ≥0.5 mL/kg/hr
8. NPO (Nil Per Oral) - absolutely nothing by mouth

2. NASOGASTRIC TUBE

9. Insert large-bore NGT (16-18 Fr) - confirm placement
10. NGT to continuous low-wall suction OR free drainage
11. Chart NGT output every 2-4 hours (volume + character)
12. Replace NGT losses: mL for mL with NS + KCl 20 mEq/L
    every 4-6 hours, guided by electrolytes
NGT decompression reduces vomiting, prevents aspiration, decreases bowel distension, and lowers risk during induction of anesthesia. - Maingot's Abdominal Operations, p. 620

3. IV FLUID RESUSCITATION

STEP A - Acute Resuscitation (First 1-2 hours)

13. IV Access: Two large-bore peripheral IVs (18G or larger)
    OR central venous line if hemodynamically unstable

14. IV FLUID BOLUS:
    Normal Saline 0.9% (NS) 500-1000 mL IV STAT
    - OR Lactated Ringer's 500-1000 mL IV STAT
    - Repeat bolus as needed to restore hemodynamic stability
    - Target: MAP >65 mmHg, HR <100 bpm
Initial vigorous crystalloid resuscitation is the most important first step. Patients often present with profound volume losses and may require large amounts of isotonic crystalloid (NS or LR). Colloids (albumin, hetastarch) have NO role. - Maingot's Abdominal Operations, p. 620

STEP B - Maintenance + Replacement Fluid

15. After initial bolus and hemodynamic stability:

    Maintenance: NS 0.9% + KCl 20 mEq/L at 125-150 mL/hr
    (Adjust rate based on UO, clinical status, and ongoing losses)

    - If vomiting has been prolonged → high risk of
      hypokalemic hypochloremic metabolic alkalosis
    - In that case prefer: NS 0.9% + KCl (not LR, which
      has no chloride replacement benefit in alkalosis)

4. ELECTROLYTE ORDERS

16. Potassium replacement:
    - Start ONLY after adequate urine output is confirmed
      (UO ≥0.5 mL/kg/hr or urine output has resumed)
    - KCl 20-40 mEq in 250 mL NS over 2-4 hours IV
    - Target serum K⁺ ≥3.5 mEq/L
    - Do NOT exceed 20 mEq/hr peripheral, 40 mEq/hr central

17. Correct hypomagnesemia if present (MgSO4 1-2 g IV)
    - Magnesium is required for refractory hypokalemia correction

18. Correct hypochloremia with NS (preferred fluid)
    - Metabolic alkalosis will resolve with Cl replacement

5. INVESTIGATIONS (ORDER AT ADMISSION)

19. Blood:
    - CBC with differential
    - BMP / CMP: Na, K, Cl, CO2, BUN, Cr, glucose
    - Serum lactate (strangulation marker)
    - LFTs
    - Serum amylase/lipase
    - PT/INR, aPTT
    - Blood group and screen (crossmatch 2 units if surgery likely)
    - ABG if respiratory compromise or hemodynamic instability

20. Imaging (if not done):
    - Plain AXR (supine + erect) STAT
    - CT Abdomen-Pelvis WITH IV contrast (preferred)
      - Identifies transition point, ischemia, closed-loop obstruction

21. ECG (baseline, especially before potassium replacement)

6. MEDICATIONS

22. Analgesia:
    - Morphine 2-4 mg IV q4h PRN (adequate analgesia does NOT
      mask peritonitis and should not be withheld)
    - OR Ketorolac 15-30 mg IV q6h (if renal function normal)

23. Antiemetics:
    - Ondansetron 4-8 mg IV q6-8h PRN nausea/vomiting

24. DVT Prophylaxis:
    - Enoxaparin 40 mg SC once daily (start after surgical
      clearance, hold if surgery imminent)
    - TED stockings / intermittent pneumatic compression

25. Antibiotics:
    - NOT routinely indicated for uncomplicated SBO
    - GIVE if strangulation suspected or surgery planned:
      Cefazolin 2 g IV within 60 min of incision
      (Add Metronidazole 500 mg IV if gross contamination)
    - Broad-spectrum (e.g., Pip-Tazo 3.375 g IV q6h) if
      peritonitis/perforation suspected
Broad-spectrum antibiotics are not indicated for uncomplicated, non-ischemic SBO being managed conservatively. - Schwartz's Principles of Surgery, 11th ed.

7. MONITORING TARGETS AND REASSESSMENT

26. Reassess fluid status every 2-4 hours:
    - Urine output ≥0.5 mL/kg/hr (adequate resuscitation)
    - Capillary refill, HR, BP, mental status
    - Repeat electrolytes in 4-6 hours after replacement
    - Repeat lactate at 4-6 hours (rising lactate = ischemia)

27. If hemodynamically unstable or poor response:
    - Consider central line / CVP monitoring
    - ICU/HDU transfer
    - Urgent surgical consult for exploratory laparotomy

8. SURGICAL ESCALATION CRITERIA (Flag Immediately)

Escalate to urgent/emergency surgery if ANY of the following:
  • Signs of peritonitis (rigid abdomen, guarding)
  • Fever + leukocytosis with rising trend
  • Rising serum lactate >2 mmol/L despite resuscitation
  • Closed-loop obstruction on CT
  • CT evidence of ischemia or pneumatosis intestinalis
  • Hemodynamic instability not responding to fluids
  • No improvement after 48 hours of conservative management

QUICK SUMMARY TABLE

ProblemOrder
Volume depletionNS or LR 500-1000 mL bolus, repeat as needed
MaintenanceNS 0.9% + KCl 20 mEq/L at 125-150 mL/hr
HypokalemiaKCl 20-40 mEq IV after confirming UO
Hypochloremic alkalosisNS 0.9% (chloride-rich), avoid LR
Ongoing NGT lossesReplace mL for mL with NS + 20 mEq KCl/L
Bowel decompressionLarge-bore NGT to suction
Monitor adequacyFoley catheter, hourly urine output

Key Principles to Remember:
  • Resuscitation = isotonic crystalloid (NS or LR); no colloids
  • Replace potassium ONLY after urine output is established (avoid hyperkalemia/arrhythmia in anuric state)
  • If prolonged vomiting history, assume hypokalemic hypochloremic alkalosis - use NS over LR
  • Urine output is the bedside guide to resuscitation adequacy
  • The fluid type used to replace NGT output should mirror what is being lost (gastric secretions = NS + KCl)
Based on: Maingot's Abdominal Operations; Schwartz's Principles of Surgery, 11e; Sabiston Textbook of Surgery; Mulholland & Greenfield's Surgery, 7e

Create a printable ICU/ward order sheet template I can use daily

Asking for Preferences
Reading File
Running Command

mkdir -p /home/daytona/workspace/sbo-order-sheet && ls /home/daytona/workspace/s…

Writing File

~/sbo-order-sheet/generate_sbo_orders.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

OUTPUT = "/home/daytona/workspace/sbo-order-sheet/SBO_Order_Sheet.pdf"

PAGE_W, PAGE_H = A4
MARGIN = 15 * mm

# ── Colour palette ─────────────────────────────────────────────────────────
NAVY    = colors.HexColor("#1a3a5c")
TEAL    = colors.HexColor("#2196A6")
LTBLUE  = colors.HexColor("#dceef5")
GRAY    = colors.HexColor("#f2f4f6")
DKGRAY  = colors.HexColor("#555555")
RED     = colors.HexColor("#c0392b")
ORANGE  = colors.HexColor("#e67e22")
GREEN   = colors.HexColor("#1e8449")
WHITE   = colors.white
BLACK   = colors.black

# ── Styles ──────────────────────────────────────────────────────────────────
base = getSampleStyleSheet()

def style(name, parent="Normal", **kw):
    s = ParagraphStyle(name, parent=base[parent], **kw)
    return s

sTitle      = style("sTitle",      fontSize=16, textColor=WHITE,  fontName="Helvetica-Bold",
                    alignment=TA_CENTER, leading=20)
sSubtitle   = style("sSubtitle",   fontSize=9,  textColor=WHITE,  fontName="Helvetica",
                    alignment=TA_CENTER, leading=12)
sSectionHdr = style("sSectionHdr", fontSize=9,  textColor=WHITE,  fontName="Helvetica-Bold",
                    alignment=TA_LEFT, leading=11)
sLabel      = style("sLabel",      fontSize=7.5, textColor=NAVY,  fontName="Helvetica-Bold",
                    alignment=TA_LEFT, leading=10)
sBody       = style("sBody",       fontSize=7.5, textColor=BLACK, fontName="Helvetica",
                    alignment=TA_LEFT, leading=10)
sSmall      = style("sSmall",      fontSize=6.5, textColor=DKGRAY,fontName="Helvetica",
                    alignment=TA_LEFT, leading=9)
sWarning    = style("sWarning",    fontSize=7.5, textColor=RED,   fontName="Helvetica-Bold",
                    alignment=TA_LEFT, leading=10)
sNote       = style("sNote",       fontSize=7,   textColor=DKGRAY,fontName="Helvetica-Oblique",
                    alignment=TA_LEFT, leading=9)
sCentered   = style("sCentered",   fontSize=7.5, textColor=BLACK, fontName="Helvetica",
                    alignment=TA_CENTER, leading=10)

CW = PAGE_W - 2 * MARGIN   # content width

# ── Helper: section banner ──────────────────────────────────────────────────
def banner(num, title, color=NAVY):
    data = [[Paragraph(f"<b>{num}. {title}</b>", sSectionHdr)]]
    t = Table(data, colWidths=[CW])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), color),
        ("TOPPADDING",  (0,0), (-1,-1), 3),
        ("BOTTOMPADDING",(0,0),(-1,-1), 3),
        ("LEFTPADDING", (0,0), (-1,-1), 6),
    ]))
    return t

# ── Helper: checkbox row ────────────────────────────────────────────────────
CHK = "☐"

def chk_row(items, cols=1):
    """items = list of (label, detail) tuples"""
    rows = []
    for label, detail in items:
        lbl_text = f"<b>{label}</b>" if label else ""
        det_text = detail or ""
        rows.append([
            Paragraph(CHK, sBody),
            Paragraph(lbl_text, sLabel),
            Paragraph(det_text, sBody),
        ])
    cw = [5*mm, 38*mm, CW - 43*mm]
    t = Table(rows, colWidths=cw, repeatRows=0)
    t.setStyle(TableStyle([
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
        ("TOPPADDING",    (0,0), (-1,-1), 1.5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 1.5),
        ("LEFTPADDING",   (0,0), (-1,-1), 2),
        ("RIGHTPADDING",  (0,0), (-1,-1), 2),
        ("LINEBELOW", (0,-1), (-1,-1), 0.3, colors.HexColor("#dddddd")),
    ]))
    return t

def chk_row_bg(items, bg=GRAY):
    rows = []
    for i, (label, detail) in enumerate(items):
        lbl_text = f"<b>{label}</b>" if label else ""
        det_text = detail or ""
        rows.append([
            Paragraph(CHK, sBody),
            Paragraph(lbl_text, sLabel),
            Paragraph(det_text, sBody),
        ])
    cw = [5*mm, 38*mm, CW - 43*mm]
    t = Table(rows, colWidths=cw)
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), bg),
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
        ("TOPPADDING",    (0,0), (-1,-1), 1.5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 1.5),
        ("LEFTPADDING",   (0,0), (-1,-1), 2),
        ("RIGHTPADDING",  (0,0), (-1,-1), 2),
        ("LINEBELOW", (0,-1), (-1,-1), 0.3, colors.HexColor("#cccccc")),
    ]))
    return t

# ── Helper: write line ──────────────────────────────────────────────────────
def write_line(label, width=60*mm):
    line = "_" * 55
    data = [[Paragraph(f"<b>{label}:</b>", sLabel), Paragraph(line, sBody)]]
    cw = [40*mm, CW - 40*mm]
    t = Table(data, colWidths=cw)
    t.setStyle(TableStyle([
        ("VALIGN", (0,0),(-1,-1), "BOTTOM"),
        ("TOPPADDING", (0,0),(-1,-1), 1),
        ("BOTTOMPADDING", (0,0),(-1,-1), 1),
        ("LEFTPADDING", (0,0),(-1,-1), 2),
    ]))
    return t

def write_lines_row(*pairs):
    """pairs = (label, width_mm) alternating"""
    row = []
    cws = []
    for label, w in pairs:
        row.append(Paragraph(f"<b>{label}:</b> {'_'*int(w/2)}", sBody))
        cws.append(w * mm)
    t = Table([row], colWidths=cws)
    t.setStyle(TableStyle([
        ("VALIGN", (0,0),(-1,-1), "BOTTOM"),
        ("TOPPADDING", (0,0),(-1,-1), 1),
        ("BOTTOMPADDING", (0,0),(-1,-1), 1),
        ("LEFTPADDING", (0,0),(-1,-1), 2),
    ]))
    return t

# ───────────────────────────────────────────────────────────────────────────
#  BUILD DOCUMENT
# ───────────────────────────────────────────────────────────────────────────
def build():
    doc = SimpleDocTemplate(
        OUTPUT,
        pagesize=A4,
        leftMargin=MARGIN, rightMargin=MARGIN,
        topMargin=MARGIN,  bottomMargin=12*mm,
        title="SBO Fluid Correction Order Sheet",
        author="Orris Clinical Tools",
    )

    story = []

    # ════════════════════════════════════════════════════════════
    # HEADER BLOCK
    # ════════════════════════════════════════════════════════════
    header_data = [[
        Paragraph("SMALL BOWEL OBSTRUCTION", sTitle),
        Paragraph("FLUID CORRECTION & MANAGEMENT ORDER SHEET", sSubtitle),
    ]]
    header = Table([[
        Paragraph("SMALL BOWEL OBSTRUCTION<br/>"
                  "<font size='9'>FLUID CORRECTION &amp; MANAGEMENT ORDER SHEET</font>",
                  sTitle),
    ]], colWidths=[CW])
    header.setStyle(TableStyle([
        ("BACKGROUND",     (0,0),(-1,-1), NAVY),
        ("TOPPADDING",     (0,0),(-1,-1), 6),
        ("BOTTOMPADDING",  (0,0),(-1,-1), 6),
        ("LEFTPADDING",    (0,0),(-1,-1), 8),
        ("ROUNDEDCORNERS", [4]),
    ]))
    story.append(header)
    story.append(Spacer(1, 3*mm))

    # ── PATIENT INFO ────────────────────────────────────────────
    info_data = [
        [
            Paragraph("<b>Patient Name:</b> " + "_"*32, sBody),
            Paragraph("<b>MRN / IP No:</b> " + "_"*20, sBody),
            Paragraph("<b>Date:</b> " + "_"*14, sBody),
        ],
        [
            Paragraph("<b>Age:</b> ____  <b>Sex:</b> ____  <b>Wt:</b> ____ kg", sBody),
            Paragraph("<b>Ward / Bed:</b> " + "_"*20, sBody),
            Paragraph("<b>Time:</b> " + "_"*14, sBody),
        ],
        [
            Paragraph("<b>Admitting Surgeon:</b> " + "_"*25, sBody),
            Paragraph("<b>Diagnosis:</b> SBO  —  ☐ Partial  ☐ Complete", sBody),
            Paragraph("<b>Allergy:</b> " + "_"*14, sBody),
        ],
    ]
    info_tbl = Table(info_data, colWidths=[CW*0.42, CW*0.36, CW*0.22])
    info_tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), GRAY),
        ("GRID",          (0,0),(-1,-1), 0.4, colors.HexColor("#cccccc")),
        ("TOPPADDING",    (0,0),(-1,-1), 3),
        ("BOTTOMPADDING", (0,0),(-1,-1), 3),
        ("LEFTPADDING",   (0,0),(-1,-1), 4),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ]))
    story.append(info_tbl)
    story.append(Spacer(1, 3*mm))

    # ════════════════════════════════════════════════════════════
    # SECTION 1 — ADMISSION & MONITORING
    # ════════════════════════════════════════════════════════════
    story.append(banner("1", "ADMISSION & MONITORING"))
    story.append(chk_row([
        ("NPO",            "Nil per oral — absolutely nothing by mouth"),
        ("Admit to",       "☐ Ward  ☐ HDU  ☐ ICU   — Bed: _________"),
        ("Activity",       "Bed rest"),
        ("Vital signs",    "Every ____ hr: BP, HR, RR, SpO₂, Temperature, GCS"),
        ("Foley catheter", "Insert urinary catheter — strict hourly urine output chart"),
        ("UO target",      "≥ 0.5 mL/kg/hr   (Patient weight: ____ kg  →  min UO: ____ mL/hr)"),
        ("Fluid balance",  "Strict I&O chart every 4 hr — running total 24 hr balance"),
        ("Weight",         "Daily morning weight (if feasible)"),
    ]))
    story.append(Spacer(1, 2*mm))

    # ════════════════════════════════════════════════════════════
    # SECTION 2 — NGT DECOMPRESSION
    # ════════════════════════════════════════════════════════════
    story.append(banner("2", "NASOGASTRIC TUBE (NGT) DECOMPRESSION", color=TEAL))
    story.append(chk_row([
        ("Insert NGT",        "Large-bore NGT (16–18 Fr) — confirm placement (CXR or auscultation)"),
        ("Suction",           "☐ Continuous low-wall suction  ☐ Free drainage to bag"),
        ("Chart NGT output",  "Record volume + character every 2–4 hr"),
        ("NGT replacement",   "Replace mL-for-mL losses with NS 0.9% + KCl 20 mEq/L  every ___hr"),
        ("NGT care",          "Flush NGT with 20 mL NS every 4 hr to maintain patency"),
    ]))
    story.append(chk_row_bg([
        ("", Paragraph(
            "⚠  NGT decompression reduces vomiting, prevents aspiration, and relieves distension. "
            "Do NOT remove until bowel function returns (flatus/stool) and output <200 mL/day.",
            sNote)),
    ], bg=colors.HexColor("#fff8e1")))
    story.append(Spacer(1, 2*mm))

    # ════════════════════════════════════════════════════════════
    # SECTION 3 — IV ACCESS & FLUID RESUSCITATION
    # ════════════════════════════════════════════════════════════
    story.append(banner("3", "IV ACCESS & FLUID RESUSCITATION"))

    # Sub-header A
    acol = colors.HexColor("#2c6e9e")
    sub_a = Table([[Paragraph("  A. ACUTE RESUSCITATION (First 1–2 hours)", sSectionHdr)]],
                   colWidths=[CW])
    sub_a.setStyle(TableStyle([
        ("BACKGROUND",(0,0),(-1,-1), acol),
        ("TOPPADDING",(0,0),(-1,-1), 2), ("BOTTOMPADDING",(0,0),(-1,-1), 2),
        ("LEFTPADDING",(0,0),(-1,-1), 6),
    ]))
    story.append(sub_a)
    story.append(chk_row([
        ("IV Access",     "Two large-bore peripheral IVs (≥18G)  OR  central line if haemodynamically unstable"),
        ("Fluid Bolus",   "☐ NS 0.9%  ☐ Lactated Ringer's   _____ mL IV OVER _____ min  →  REPEAT PRN"),
        ("Bolus target",  "MAP ≥ 65 mmHg  |  HR < 100 bpm  |  UO ≥ 0.5 mL/kg/hr"),
        ("No colloids",   "Albumin / hetastarch are NOT indicated in SBO resuscitation"),
    ]))

    # Sub-header B
    sub_b = Table([[Paragraph("  B. MAINTENANCE & REPLACEMENT FLUIDS (After stabilisation)", sSectionHdr)]],
                   colWidths=[CW])
    sub_b.setStyle(TableStyle([
        ("BACKGROUND",(0,0),(-1,-1), acol),
        ("TOPPADDING",(0,0),(-1,-1), 2), ("BOTTOMPADDING",(0,0),(-1,-1), 2),
        ("LEFTPADDING",(0,0),(-1,-1), 6),
    ]))
    story.append(sub_b)

    fluid_rows = [
        [Paragraph("<b>Fluid</b>", sLabel),
         Paragraph("<b>Rate</b>", sLabel),
         Paragraph("<b>Duration / Notes</b>", sLabel)],
        [Paragraph("☐  NS 0.9% + KCl 20 mEq/L", sBody),
         Paragraph("_____ mL/hr", sBody),
         Paragraph("Standard maintenance — adjust to UO", sBody)],
        [Paragraph("☐  Lactated Ringer's (LR)", sBody),
         Paragraph("_____ mL/hr", sBody),
         Paragraph("Use if no prolonged vomiting / no alkalosis", sBody)],
        [Paragraph("☐  NS 0.9% (plain) + KCl additive", sBody),
         Paragraph("_____ mL/hr", sBody),
         Paragraph("Preferred if hypochloraemic alkalosis present", sBody)],
        [Paragraph("☐  NGT loss replacement", sBody),
         Paragraph("mL for mL", sBody),
         Paragraph("NS 0.9% + KCl 20 mEq/L — replace every ___hr", sBody)],
    ]
    ftbl = Table(fluid_rows, colWidths=[CW*0.38, CW*0.18, CW*0.44])
    ftbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0), LTBLUE),
        ("FONTNAME",      (0,0),(-1,0), "Helvetica-Bold"),
        ("GRID",          (0,0),(-1,-1), 0.4, colors.HexColor("#bbbbbb")),
        ("TOPPADDING",    (0,0),(-1,-1), 2.5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 2.5),
        ("LEFTPADDING",   (0,0),(-1,-1), 4),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GRAY]),
    ]))
    story.append(ftbl)
    story.append(Spacer(1, 2*mm))

    # ════════════════════════════════════════════════════════════
    # SECTION 4 — ELECTROLYTE CORRECTION
    # ════════════════════════════════════════════════════════════
    story.append(banner("4", "ELECTROLYTE CORRECTION", color=colors.HexColor("#1e6e4a")))
    story.append(chk_row_bg([
        ("", Paragraph(
            "⚠  Start potassium replacement ONLY after confirming adequate urine output (≥0.5 mL/kg/hr). "
            "Never replace K⁺ in an anuric/oliguric patient without senior review.",
            sWarning)),
    ], bg=colors.HexColor("#fdecea")))

    elec_rows = [
        [Paragraph("<b>Electrolyte</b>", sLabel),
         Paragraph("<b>Typical deficit in SBO</b>", sLabel),
         Paragraph("<b>Replacement order</b>", sLabel)],
        [Paragraph("Potassium (K⁺)", sBody),
         Paragraph("Low (↓ from vomiting)", sBody),
         Paragraph("KCl 20–40 mEq in 250 mL NS over 2–4 hr IV\n"
                   "Max rate: 20 mEq/hr peripheral / 40 mEq/hr central\n"
                   "Target K⁺ ≥ 3.5 mEq/L\n"
                   "☐ Oral KCl _____ mEq BD (if NGT clamped)", sSmall)],
        [Paragraph("Chloride (Cl⁻)", sBody),
         Paragraph("Low — hypochloraemic metabolic alkalosis", sBody),
         Paragraph("Correct with NS 0.9% (chloride-rich)\n"
                   "Alkalosis resolves as Cl⁻ and volume restored", sSmall)],
        [Paragraph("Magnesium (Mg²⁺)", sBody),
         Paragraph("Low (if prolonged poor intake)", sBody),
         Paragraph("MgSO₄ 1–2 g in 100 mL NS over 30–60 min IV\n"
                   "Required for refractory hypokalaemia correction", sSmall)],
        [Paragraph("Sodium (Na⁺)", sBody),
         Paragraph("May be low or normal", sBody),
         Paragraph("Correct slowly if hyponatraemic\n"
                   "≤ 8–10 mEq/L per 24 hr to avoid osmotic demyelination", sSmall)],
    ]
    etbl = Table(elec_rows, colWidths=[CW*0.18, CW*0.28, CW*0.54])
    etbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0), colors.HexColor("#c8e6c9")),
        ("FONTNAME",      (0,0),(-1,0), "Helvetica-Bold"),
        ("GRID",          (0,0),(-1,-1), 0.4, colors.HexColor("#bbbbbb")),
        ("TOPPADDING",    (0,0),(-1,-1), 2.5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 2.5),
        ("LEFTPADDING",   (0,0),(-1,-1), 4),
        ("VALIGN",        (0,0),(-1,-1), "TOP"),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GRAY]),
    ]))
    story.append(etbl)
    story.append(Spacer(1, 2*mm))

    # ════════════════════════════════════════════════════════════
    # SECTION 5 — INVESTIGATIONS
    # ════════════════════════════════════════════════════════════
    story.append(banner("5", "INVESTIGATIONS", color=colors.HexColor("#5d3e8e")))

    # Two-column checklist
    inv_left = [
        ("CBC + differential", ""),
        ("BMP/CMP",  "Na, K, Cl, CO₂, BUN, Creatinine, Glucose"),
        ("Serum lactate", "STAT — repeat at 4–6 hr  (↑ = ischaemia)"),
        ("LFTs + Amylase/Lipase", ""),
        ("Coagulation", "PT / INR / aPTT"),
        ("Blood group & screen", "Crossmatch 2 units if surgery likely"),
        ("ABG", "If haemodynamic instability or SpO₂ <94%"),
    ]
    inv_right = [
        ("AXR Erect + Supine", "STAT — air-fluid levels, bowel calibre"),
        ("CT Abd-Pelvis + IV contrast", "PREFERRED — transition point, ischaemia, closed-loop"),
        ("Ultrasound abdomen", "If CT unavailable / pregnant patient"),
        ("ECG", "Baseline before K⁺ replacement"),
        ("Urine R/E + C/S", ""),
        ("Repeat electrolytes", "4–6 hr after replacement commenced"),
        ("Repeat lactate", "At 4 hr — if rising → urgent surgical review"),
    ]

    def inv_col(items):
        rows = []
        for label, detail in items:
            d = f" — {detail}" if detail else ""
            rows.append([Paragraph(CHK, sBody),
                         Paragraph(f"<b>{label}</b>{d}", sSmall)])
        t = Table(rows, colWidths=[5*mm, (CW/2)-8*mm])
        t.setStyle(TableStyle([
            ("VALIGN",        (0,0),(-1,-1), "TOP"),
            ("TOPPADDING",    (0,0),(-1,-1), 1.5),
            ("BOTTOMPADDING", (0,0),(-1,-1), 1.5),
            ("LEFTPADDING",   (0,0),(-1,-1), 2),
        ]))
        return t

    inv_tbl = Table([[inv_col(inv_left), inv_col(inv_right)]], colWidths=[CW/2, CW/2])
    inv_tbl.setStyle(TableStyle([
        ("VALIGN",      (0,0),(-1,-1), "TOP"),
        ("LINEAFTER",   (0,0),(0,-1),  0.4, colors.HexColor("#cccccc")),
    ]))
    story.append(inv_tbl)
    story.append(Spacer(1, 2*mm))

    # ════════════════════════════════════════════════════════════
    # SECTION 6 — MEDICATIONS
    # ════════════════════════════════════════════════════════════
    story.append(banner("6", "MEDICATIONS", color=colors.HexColor("#7b3f00")))
    story.append(chk_row([
        ("Analgesia",      "Morphine 2–4 mg IV q4h PRN  OR  Ketorolac 15–30 mg IV q6h (if renal fn normal)"),
        ("Antiemetic",     "Ondansetron 4–8 mg IV q6–8h PRN nausea/vomiting"),
        ("PPI / H2",       "Pantoprazole 40 mg IV OD (stress ulcer prophylaxis)"),
        ("DVT Prophylaxis","Enoxaparin 40 mg SC OD — START after surgical clearance (hold if surgery imminent)"),
        ("                 Mechanical", "TED stockings + Intermittent pneumatic compression (IPC)"),
    ]))
    story.append(chk_row_bg([
        ("Antibiotics", "NOT routinely indicated for uncomplicated SBO"),
        ("Give if strangulation / surgery:", "Cefazolin 2 g IV within 60 min of incision  ±  Metronidazole 500 mg IV"),
        ("If peritonitis / perforation:",    "Pip-Tazo 4.5 g IV q8h  OR  Meropenem 1 g IV q8h"),
    ], bg=colors.HexColor("#fff3e0")))
    story.append(Spacer(1, 2*mm))

    # ════════════════════════════════════════════════════════════
    # SECTION 7 — MONITORING TARGETS & REASSESSMENT
    # ════════════════════════════════════════════════════════════
    story.append(banner("7", "MONITORING TARGETS & REASSESSMENT SCHEDULE"))

    target_data = [
        [Paragraph("<b>Parameter</b>", sLabel),
         Paragraph("<b>Target</b>", sLabel),
         Paragraph("<b>Frequency</b>", sLabel),
         Paragraph("<b>Action if not met</b>", sLabel)],
        [Paragraph("Urine output", sBody),
         Paragraph("≥ 0.5 mL/kg/hr", sBody),
         Paragraph("Hourly", sBody),
         Paragraph("500 mL fluid bolus → reassess; if no response → senior review", sSmall)],
        [Paragraph("Mean arterial pressure", sBody),
         Paragraph("≥ 65 mmHg", sBody),
         Paragraph("1–2 hrly", sBody),
         Paragraph("Fluid bolus; consider vasopressors if unresponsive", sSmall)],
        [Paragraph("Heart rate", sBody),
         Paragraph("< 100 bpm", sBody),
         Paragraph("1–2 hrly", sBody),
         Paragraph("Review fluid status, rule out sepsis/ischaemia", sSmall)],
        [Paragraph("Serum K⁺", sBody),
         Paragraph("3.5–5.0 mEq/L", sBody),
         Paragraph("4–6 hrly", sBody),
         Paragraph("Replace as per Section 4 protocol", sSmall)],
        [Paragraph("Serum lactate", sBody),
         Paragraph("< 2.0 mmol/L", sBody),
         Paragraph("At admission + 4–6 hr", sBody),
         Paragraph("Rising lactate → URGENT surgical review for ischaemia", sSmall)],
        [Paragraph("NGT output", sBody),
         Paragraph("Chart; replace mL:mL", sBody),
         Paragraph("Every 2–4 hr", sBody),
         Paragraph("Replace with NS + KCl 20 mEq/L", sSmall)],
        [Paragraph("Abdominal exam", sBody),
         Paragraph("No peritonism", sBody),
         Paragraph("Every 4–6 hr", sBody),
         Paragraph("New peritonism → immediate surgical consult", sSmall)],
        [Paragraph("Electrolytes repeat", sBody),
         Paragraph("Within normal range", sBody),
         Paragraph("4–6 hr post replacement", sBody),
         Paragraph("Adjust replacement as needed", sSmall)],
    ]
    ttbl = Table(target_data, colWidths=[CW*0.2, CW*0.17, CW*0.17, CW*0.46])
    ttbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0), LTBLUE),
        ("FONTNAME",      (0,0),(-1,0), "Helvetica-Bold"),
        ("GRID",          (0,0),(-1,-1), 0.4, colors.HexColor("#bbbbbb")),
        ("TOPPADDING",    (0,0),(-1,-1), 2),
        ("BOTTOMPADDING", (0,0),(-1,-1), 2),
        ("LEFTPADDING",   (0,0),(-1,-1), 4),
        ("VALIGN",        (0,0),(-1,-1), "TOP"),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GRAY]),
    ]))
    story.append(ttbl)
    story.append(Spacer(1, 2*mm))

    # ════════════════════════════════════════════════════════════
    # SECTION 8 — ESCALATION CRITERIA
    # ════════════════════════════════════════════════════════════
    story.append(banner("8", "SURGICAL ESCALATION — CALL SURGEON IMMEDIATELY IF ANY:", color=RED))
    esc_data = [
        [Paragraph("☐  Signs of peritonitis (rigid abdomen, involuntary guarding, rebound tenderness)", sBody),
         Paragraph("☐  Rising serum lactate > 2 mmol/L despite adequate resuscitation", sBody)],
        [Paragraph("☐  Fever + progressive leukocytosis (WBC > 15,000)", sBody),
         Paragraph("☐  CT evidence: closed-loop obstruction, pneumatosis intestinalis, free air", sBody)],
        [Paragraph("☐  Haemodynamic instability not responding to 2 L fluid resuscitation", sBody),
         Paragraph("☐  No clinical improvement after 48 hr conservative management", sBody)],
        [Paragraph("☐  Complete SBO confirmed on CT (no gas in colon/rectum)", sBody),
         Paragraph("☐  Strangulation suspected (constant severe pain, tachycardia, fever)", sBody)],
    ]
    etbl2 = Table(esc_data, colWidths=[CW/2, CW/2])
    etbl2.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), colors.HexColor("#fdecea")),
        ("GRID",          (0,0),(-1,-1), 0.4, colors.HexColor("#e8b4b0")),
        ("TOPPADDING",    (0,0),(-1,-1), 2.5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 2.5),
        ("LEFTPADDING",   (0,0),(-1,-1), 4),
        ("VALIGN",        (0,0),(-1,-1), "TOP"),
    ]))
    story.append(etbl2)
    story.append(Spacer(1, 2*mm))

    # ════════════════════════════════════════════════════════════
    # SECTION 9 — QUICK REFERENCE
    # ════════════════════════════════════════════════════════════
    story.append(banner("9", "QUICK REFERENCE — FLUID SELECTION GUIDE", color=colors.HexColor("#2c6e9e")))

    qr_data = [
        [Paragraph("<b>Clinical Scenario</b>", sLabel),
         Paragraph("<b>Preferred Fluid</b>", sLabel),
         Paragraph("<b>Additive / Rate</b>", sLabel)],
        [Paragraph("Acute volume depletion (initial)", sBody),
         Paragraph("NS 0.9% OR Lactated Ringer's", sBody),
         Paragraph("500–1000 mL bolus; repeat PRN", sSmall)],
        [Paragraph("Maintenance (haemodynamically stable)", sBody),
         Paragraph("NS 0.9%", sBody),
         Paragraph("+ KCl 20 mEq/L @ 100–150 mL/hr", sSmall)],
        [Paragraph("Prolonged vomiting / hypochloraemic alkalosis", sBody),
         Paragraph("NS 0.9% (NOT LR)", sBody),
         Paragraph("+ KCl; LR lacks chloride — avoid", sSmall)],
        [Paragraph("Replace ongoing NGT losses", sBody),
         Paragraph("NS 0.9%", sBody),
         Paragraph("+ KCl 20 mEq/L; mL-for-mL q4–6h", sSmall)],
        [Paragraph("Hypokalaemia correction", sBody),
         Paragraph("KCl 20–40 mEq in 250 mL NS", sBody),
         Paragraph("Over 2–4 hr IV; max 20 mEq/hr peripheral", sSmall)],
        [Paragraph("Hypomagnesaemia (refractory hypokalaemia)", sBody),
         Paragraph("MgSO₄ 1–2 g in 100 mL NS", sBody),
         Paragraph("Over 30–60 min IV", sSmall)],
        [Paragraph("Haemodynamic instability + poor response", sBody),
         Paragraph("Escalate — ICU / CVP monitoring", sBody),
         Paragraph("Consider vasopressors; surgical review", sSmall)],
    ]
    qrtbl = Table(qr_data, colWidths=[CW*0.35, CW*0.32, CW*0.33])
    qrtbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0), LTBLUE),
        ("FONTNAME",      (0,0),(-1,0), "Helvetica-Bold"),
        ("GRID",          (0,0),(-1,-1), 0.4, colors.HexColor("#bbbbbb")),
        ("TOPPADDING",    (0,0),(-1,-1), 2.5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 2.5),
        ("LEFTPADDING",   (0,0),(-1,-1), 4),
        ("VALIGN",        (0,0),(-1,-1), "TOP"),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GRAY]),
    ]))
    story.append(qrtbl)
    story.append(Spacer(1, 2*mm))

    # ════════════════════════════════════════════════════════════
    # SIGNATURES
    # ════════════════════════════════════════════════════════════
    story.append(banner("10", "ORDERS WRITTEN BY", color=DKGRAY))
    sig_data = [
        [
            Paragraph("<b>Ordering Physician:</b> " + "_"*28, sBody),
            Paragraph("<b>Designation:</b> " + "_"*20, sBody),
            Paragraph("<b>Date/Time:</b> " + "_"*16, sBody),
        ],
        [
            Paragraph("<b>Signature:</b> " + "_"*30, sBody),
            Paragraph("<b>Contact / Bleep:</b> " + "_"*18, sBody),
            Paragraph("<b>Countersign:</b> " + "_"*16, sBody),
        ],
    ]
    sig_tbl = Table(sig_data, colWidths=[CW*0.42, CW*0.33, CW*0.25])
    sig_tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), GRAY),
        ("GRID",          (0,0),(-1,-1), 0.4, colors.HexColor("#cccccc")),
        ("TOPPADDING",    (0,0),(-1,-1), 3),
        ("BOTTOMPADDING", (0,0),(-1,-1), 3),
        ("LEFTPADDING",   (0,0),(-1,-1), 4),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ]))
    story.append(sig_tbl)
    story.append(Spacer(1, 2*mm))

    # ════════════════════════════════════════════════════════════
    # FOOTER NOTE
    # ════════════════════════════════════════════════════════════
    story.append(HRFlowable(width=CW, thickness=0.5, color=TEAL))
    story.append(Spacer(1, 1*mm))
    footer_txt = (
        "Based on: Maingot's Abdominal Operations | Schwartz's Principles of Surgery 11e | "
        "Sabiston Textbook of Surgery | Mulholland &amp; Greenfield's Surgery 7e | StatPearls SBO Guidelines.   "
        "This template is a clinical aid — all orders must be reviewed and signed by a licensed physician. "
        "Doses must be adjusted for patient weight, renal function, and clinical status."
    )
    story.append(Paragraph(footer_txt, sNote))

    # ── BUILD ──────────────────────────────────────────────────
    doc.build(story)
    print(f"PDF saved to: {OUTPUT}")

if __name__ == "__main__":
    build()
Running Command

cd /home/daytona/workspace/sbo-order-sheet && python generate_sbo_orders.py 2>&1

Editing File

~/sbo-order-sheet/generate_sbo_orders.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/sbo-order-sheet/generate_sbo_orders.py'
Editing File

~/sbo-order-sheet/generate_sbo_orders.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/sbo-order-sheet/generate_sbo_orders.py'
Editing File

~/sbo-order-sheet/generate_sbo_orders.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/sbo-order-sheet/generate_sbo_orders.py'
Running Command

cd /home/daytona/workspace/sbo-order-sheet && python generate_sbo_orders.py 2>&1

Running Command

ls -lh /home/daytona/workspace/sbo-order-sheet/SBO_Order_Sheet.pdf && python3 -c…

Your printable SBO order sheet is ready - 2 pages, A4 format:

SBO Order Sheet

PDF Document · PDF


What's included in the PDF:
SectionContents
Patient Info HeaderName, MRN, Age/Sex/Weight, Ward/Bed, Surgeon, Allergy, Date/Time
1. Admission & MonitoringNPO, vitals frequency, Foley catheter, UO target calculator, I&O chart
2. NGT DecompressionSize, suction type, output charting, mL-for-mL replacement formula
3. IV Fluid ResuscitationBolus phase (NS/LR, targets) + maintenance table with fluid choices & rates
4. Electrolyte CorrectionK⁺, Cl⁻, Mg²⁺, Na⁺ — deficit, dose, rate, max infusion rules + RED warning box
5. InvestigationsTwo-column checklist (bloods + imaging) with clinical notes
6. MedicationsAnalgesia, antiemetics, PPI, DVT prophylaxis, antibiotic guide by severity
7. Monitoring TargetsTable with parameter → target → frequency → action if not met
8. Surgical EscalationRed-highlighted 8-point escalation criteria checklist
9. Quick ReferenceFluid selection guide by clinical scenario
10. SignaturesOrdering physician, designation, countersign fields
The sheet uses checkbox (☐) format throughout so you can tick items as you write orders. Print at 100% scale on A4 paper.
This is a shared conversation. Sign in to Orris to start your own chat.