ข้ามไปที่เนื้อหา

API Reference

หน้านี้บันทึก public surface ของแต่ละโมดูล roots_hemms_* — โมเดล ฟิลด์ และเมท็อดที่โมดูลอื่น (รวมถึงของคุณ) คาดหวังว่าจะ สืบทอด เรียก หรืออ้างอิง โดยตั้งใจคัดเลือกมา: helper ภายในและเมท็อด compute ที่ไม่ใช่จุดขยายจะถูก ละเว้น อ่าน source สำหรับสิ่งเหล่านั้น

ธรรมเนียมที่ใช้ในหน้านี้

  • โมเดลใหม่ ที่ HEMMS ประกาศใช้คำนำหน้า _name ว่า hemms.
  • ฟิลด์เฉพาะของโรงพยาบาล ที่เพิ่มเข้าในโมเดลที่สืบทอดมา (Odoo / OCA) ใช้คำนำหน้า roots_
  • "จุดขยาย" ระบุเมท็อดที่ออกแบบให้เขียนทับได้ ผ่าน super() ในโค้ดปลายน้ำ

สำหรับภาพรวมที่ใหญ่ขึ้น อ่าน สถาปัตยกรรม ก่อน สำหรับ วิธีเพิ่มโมดูลใหม่ที่ขยายสิ่งเหล่านี้ อ่าน การพัฒนาโมดูล


เครื่องมือแพทย์ & ระดับความวิกฤต

โมดูลเหล่านี้ประกอบเป็นแกนกลางของ asset master + การจำแนกความเสี่ยงที่ ทุกโมดูล HEMMS อื่น ๆ พึ่งพา

roots_hemms_criticality

เพิ่มเมทริกซ์ความวิกฤตแบบไฟจราจร 2 มิติ Value × Risk บน maintenance.equipment

โมเดล: maintenance.equipment (_inherit)

ฟิลด์ ชนิด หมายเหตุ
roots_value_tier Selection (low / medium / high) จำเป็น, ติดตาม, ค่าเริ่มต้น medium
roots_risk_tier Selection (low / medium / high) จำเป็น, ติดตาม, ค่าเริ่มต้น medium
roots_criticality_color Selection (green / yellow / red) compute ที่เก็บค่าจากเมทริกซ์ 2 มิติ; มี index
roots_criticality_label Char ป้ายสองภาษาที่ไม่เก็บค่า ตาม lang ของผู้ใช้

ตัวเมทริกซ์เองคือ CRITICALITY_MATRIX ใน models/maintenance_equipment.py — dict แบบ (value_tier, risk_tier) → color เขียนทับเมท็อด compute _compute_roots_criticality_color ได้หาก คุณต้องการ mapping ที่ต่างออกไป

roots_hemms_asset_master

ข้อมูลหลัก Brand / Model และความไม่ซ้ำของรหัสครุภัณฑ์ของราชการ

โมเดล:

  • hemms.equipment.brand — ข้อมูลหลัก Brand (_inherit = ["mail.thread"]) เมท็อด action action_model_list() และ action_equipment_list() สำหรับ stat button
  • hemms.equipment.model — ข้อมูลหลัก Model, M2O ไปยัง brand โดเมน [('brand_id', '=', brand_id)] ถูกบังคับใช้บน maintenance.equipment.equipment_model_id

โมเดล: maintenance.equipment (_inherit)

ฟิลด์ ชนิด หมายเหตุ
brand_id M2O hemms.equipment.brand ติดตาม, มี index
equipment_model_id M2O hemms.equipment.model กรองโดเมนตาม brand
current_condition Selection in_use / broken / deteriorated / lost / unused ป้ายสองภาษา; มี index; ติดตาม

SQL constraint: ref (ฟิลด์เดิมของ Odoo ที่เพิ่มโดย OCA maintenance_equipment_ref) ถูกบังคับให้ไม่ซ้ำที่นี่ — รหัสครุภัณฑ์ ทางการไม่สามารถชนกันข้ามระเบียนเครื่องมือแพทย์ได้


ขั้นตอนการทำงาน & PM

roots_hemms_workflow

ขั้นตอนการทำงานการซ่อม BME ไทย 5 ขั้น พร้อมการติดตาม SLA และ ร่องรอยการตรวจสอบที่แก้ไขไม่ได้

โมเดล: maintenance.stage (_inherit)

ฟิลด์ ชนิด หมายเหตุ
roots_description_th Text (translate) คำอธิบายภาษาไทย
roots_sla_hours Float จำนวนชั่วโมงสูงสุดที่ request ควรอยู่ในขั้นนี้
roots_is_done_stage Boolean ทำเครื่องหมายขั้นปลายทาง
roots_responsible_role Selection ward_staff / bme_manager / bme_technician / bme_manager_signoff

โมเดล: maintenance.request (_inherit)

ฟิลด์ ชนิด หมายเหตุ
roots_stage_entered_at Datetime ตั้งค่าเมื่อเปลี่ยนขั้น; ค่าเริ่มต้น now; copy=False
roots_time_in_current_stage_hours Float compute ที่ไม่เก็บค่า
roots_is_sla_breached Boolean compute ที่ไม่เก็บค่า + search แบบกำหนดเอง (_search_roots_is_sla_breached) ที่ผลักการเปรียบเทียบเข้าไปใน SQL
roots_equipment_criticality_color Selection (related, stored) ภาพสะท้อนความวิกฤตของเครื่องมือแพทย์เพื่อระบายสี kanban
roots_current_responsible_user_id M2O res.users compute ที่เก็บค่า; ไม่ fall back ไปยัง env.user
roots_stage_transition_log_ids One2many รายการ audit-log

จุดขยาย บน maintenance.request:

  • create() — บันทึกแถวการเปลี่ยนผ่านเริ่มต้นจาก False → stage_id
  • write() — เมื่อ stage_id กำลังถูกเปลี่ยน จะจับ from_stage, to_stage, เวลาในขั้นก่อนหน้า และโพสต์โน้ตใน chatter รัน super ก่อนเพื่อให้ access error ยกเลิกก่อนเกิด log ที่กำพร้า

โมเดล: hemms.stage.transition.log — แถว audit แบบ append-only เก็บ อยู่ใน maintenance.request.roots_stage_transition_log_ids แต่ละแถว บันทึก from_stage_id, to_stage_id, transitioned_at, transitioned_by_id, roots_time_in_previous_stage_hours

การค้นหาการละเมิด SLA

breached = env["maintenance.request"].search([
    ("roots_is_sla_breached", "=", True),
    ("equipment_id.roots_criticality_color", "=", "red"),
])

roots_hemms_pm

ชนิด PM ของโรงพยาบาล (สองภาษา) และการกำหนดเส้นทางขั้นตอนแบบรับรู้ PM

โมเดล: maintenance.kind (_inherit) — เพิ่ม roots_name_th และ roots_description

โมเดล: maintenance.stage (_inherit) — เพิ่ม roots_is_pm_initial_stage (Boolean) พร้อม SQL exclusion constraint เพื่อให้มีเพียงขั้นเดียวที่เป็นขั้นเริ่มต้นของ PM ได้

โมเดล: maintenance.request (_inherit)

การเขียนทับ create() กำหนดเส้นทาง request ใด ๆ ที่มาพร้อม maintenance_plan_id ไปยังขั้นเริ่มต้นของ PM (เว้นแต่ผู้เรียก ระบุ stage_id อย่างชัดเจน) ค่าเริ่มต้นของ stage_id ถูกเขียนทับ ผ่าน _roots_default_stage_excluding_pm() — request เชิงแก้ไขจะข้าม ขั้น PM เมื่อสร้าง

หากคุณต้องการเพิ่มชนิด PM ใหม่ ให้ประกาศใน data/maintenance_kind_data.xml ของโมดูลคุณเอง:

<record id="kind_calibration" model="maintenance.kind">
    <field name="name">Calibration</field>
    <field name="roots_name_th">การสอบเทียบ</field>
    <field name="roots_description">Verify accuracy against a traceable reference.</field>
</record>

การตรวจสอบสินทรัพย์ประจำปี (ปจป.)

roots_hemms_asset_inspection

โมเดล: hemms.asset.inspection — หนึ่งระเบียนต่อ (department_id, fiscal_year_be) บล็อก _sql_constraints ป้องกันการซ้ำของชุดนี้

ฟิลด์สำคัญ:

ฟิลด์ ชนิด หมายเหตุ
name Char running ref AI/YYYY/NNNNN ผ่าน ir.sequence
fiscal_year_be Selection ปีงบประมาณ พ.ศ. ของไทย; หน้าต่าง ±10 ปี
department_id M2O hr.department จำเป็น, ติดตาม
chair_id, committee_member_1_id, committee_member_2_id M2O hr.employee constraint บุคคลต้องไม่ซ้ำกัน
state Selection draftin_progresssubmitted
line_ids O2M หนึ่งแถวต่อเครื่องมือแพทย์ที่ถูกตรวจสอบ
count_* Integer compute ที่เก็บค่า: broken / deteriorated / lost / unused / in_use / unmarked / total

เมท็อด action สาธารณะ (button handler):

  • action_open_add_equipment_wizard() — เฉพาะ Draft
  • action_start_inspection()draftin_progress ปฏิเสธหากไม่มี line_ids
  • action_submit()in_progresssubmitted ปฏิเสธหากมีบรรทัดใด ที่ไม่ได้ตั้ง condition เรียก _propagate_condition_to_master()
  • action_reset_to_draft() — เฉพาะ Maintenance Manager
  • action_print_report() — เรนเดอร์ PDF ปจป.

_propagate_condition_to_master() เขียน condition สุดท้ายของแต่ละบรรทัด กลับไปยัง maintenance.equipment.current_condition แบบ bulk ต่อ condition — หนึ่ง UPDATE ต่อค่าที่ต่างกันแต่ละค่า

โมเดล: hemms.asset.inspection.line — บรรทัด เครื่องมือแพทย์ × การตรวจสอบ พร้อม condition ที่สังเกตได้


อะไหล่

roots_hemms_spare_parts

โมเดล: hemms.equipment.spare.line — เทมเพลตอะไหล่ ต่อเครื่องมือแพทย์

ฟิลด์ ชนิด หมายเหตุ
equipment_id M2O maintenance.equipment จำเป็น, ondelete='cascade', มี index
product_id M2O product.product โดเมน [('type', 'in', ['product', 'consu'])]
default_qty Float UoM digits
uom_id Related (read-only) จาก product
kind_ids M2M maintenance.kind จำกัดเฉพาะชนิด PM บางชนิด; ว่าง = ทั้งหมด
roots_is_critical Boolean compute ที่เก็บค่า: product ถูกระบุว่าวิกฤต หรือเครื่องมือแพทย์เป็นสีแดง
qty_available Related (read-only) จาก product

Cron: _cron_check_critical_low_stock — รายวัน; ยกกิจกรรม Warning บนเครื่องมือแพทย์สำหรับอะไหล่วิกฤตใด ๆ ที่มีในมือ ≤ 0 ขจัดความซ้ำกับกิจกรรมที่มีอยู่ซึ่งตรงกับชื่อ product

โมเดล: product.template (_inherit) — เพิ่ม roots_is_critical_spare และ roots_name_th

โมเดล: maintenance.request (_inherit) — สร้าง picking Consumption แบบ draft โดยอัตโนมัติบน request จาก PM-cron ผ่าน _roots_auto_create_spare_picking() picking จะกรองบรรทัดอะไหล่ ตาม kind_ids (บรรทัดที่ไม่มีข้อจำกัดชนิดจะถูกรวมเสมอ)

ยังเพิ่ม roots_open_picking_count (compute ที่ไม่เก็บค่า) และ action_view_pending_stock_pickings() สำหรับ stat button

โมเดล: stock.picking (_inherit) — หมายเลข Stock Request แบบ running ผ่าน ir.sequence ของ hemms.stock.request บน picking ชนิด Consumption


สัญญาบริการ

roots_hemms_service_contracts

โมเดล: hemms.contract.type — คำศัพท์ (Warranty, Extended, MA, Spare-only, Labor-only, ...) name สองภาษา + roots_name_th, code ไม่ซ้ำ, มีการเรียงลำดับ

โมเดล: hemms.service.contract — ส่วนหัวของสัญญา

ฟิลด์สำคัญ:

ฟิลด์ ชนิด หมายเหตุ
name, roots_name_th Char สองภาษา; display_name คือ [REF] EN / TH
reference Char running ref ผ่าน sequence hemms.service.contract (SC/YYYY/NNNN); ไม่ซ้ำ
partner_id M2O res.partner ผู้ขาย; การกรองด้วย flag supplier ถูกเลื่อนออกไป (ดู I1 ใน Release Notes)
contract_type_id M2O hemms.contract.type ondelete='restrict'
equipment_ids M2M maintenance.equipment hemms_contract_equipment_rel
coverage_line_ids O2M hemms.service.contract.coverage.line ความครอบคลุมต่อชนิด
date_start, date_end Date CHECK constraint: start ≤ end
state Selection (stored compute) draft / active / expired / cancelled — cancelled ติดแน่น
roots_sla_tier Selection Bronze / Silver / Gold / Platinum (แสดงผลเท่านั้นใน Q3)
roots_renewal_alert_days Integer ค่าเริ่มต้น 60
roots_renewal_alerted Boolean ตั้งค่าโดย cron เพื่อเลี่ยงความซ้ำ

action สาธารณะ: action_set_cancelled(), action_set_draft(), action_view_equipment(), action_view_requests()

Cron: _cron_update_state_and_alert — รายวัน; เลื่อน draft → active และ active → expired ตามวันที่ จากนั้นยิง mail.activity บนผู้รับผิดชอบเมื่อถึง roots_renewal_alert_date แล้ว Cancelled ยังคงเป็น cancelled

การค้นหาสองภาษา: _name_search() ถูกเขียนทับให้จับคู่ name หรือ roots_name_th หรือ reference

โมเดล: hemms.service.contract.coverage.line — เมทริกซ์ต่อชนิด

ฟิลด์ ชนิด หมายเหตุ
kind_id M2O maintenance.kind จำเป็น
included_in_contract Boolean ค่าเริ่มต้น True
billable_to_hospital Boolean งบของใครเป็นผู้จ่าย

โมเดล: maintenance.equipment (_inherit) — เพิ่ม roots_active_contract_id (stored compute) และ roots_active_contract_type_code (related) มีประโยชน์สำหรับการ เชื่อม request ใหม่โดยอัตโนมัติ:

equipment.roots_active_contract_id   # the contract covering this equipment right now

โมเดล: maintenance.request (_inherit)

ฟิลด์ ชนิด หมายเหตุ
roots_service_contract_id M2O (stored compute, เขียนได้) เติมอัตโนมัติเมื่อว่าง — การเขียนทับด้วยมือจะติดแน่น (แผน I8)
roots_is_billable_to_hospital Boolean (stored compute) True เว้นแต่ครอบคลุม และไม่เรียกเก็บจากโรงพยาบาล
roots_contract_warning Char (compute) ข้อความบนแบนเนอร์
roots_contract_warning_level Selection (compute) success / info / warning สำหรับ alert-class บนฟอร์ม

การสร้างสัญญาแบบเขียนโค้ด

env["hemms.service.contract"].create({
    "name": "MRI 1.5T - 5yr MA",
    "partner_id": vendor.id,
    "contract_type_id": env.ref(
        "roots_hemms_service_contracts.contract_type_ma"
    ).id,
    "date_start": "2026-01-01",
    "date_end": "2031-12-31",
    "equipment_ids": [(6, 0, [mri.id])],
    "coverage_line_ids": [
        (0, 0, {
            "kind_id": env.ref("roots_hemms_pm.kind_calibration").id,
            "included_in_contract": True,
            "billable_to_hospital": False,
        }),
    ],
})

e-Signature

roots_hemms_signature

โมดูลสะพานล้วน ๆ — ไม่เพิ่มโมเดลใหม่ มีเพียง _inherit sign.oca.request, hemms.asset.inspection, และ hemms.service.contract

โมเดล: sign.oca.request (_inherit)

เพิ่ม stored M2O compute จาก record_ref แบบ polymorphic:

  • hemms_asset_inspection_id
  • hemms_service_contract_id

สิ่งเหล่านี้ทำให้โมเดลของโรงพยาบาลที่เชื่อมต่อสามารถประกาศ inverse แบบ One2many ได้ เนื่องจากฟิลด์ Reference ไม่สามารถเป็น inverse_name ได้โดยตรง

จุดขยาย: _check_signed() — ถูกเขียนทับ หลังจาก super()._check_signed() อาจเปลี่ยน state ไปเป็น 2_signed แล้ว การเขียนทับจะดูที่ record_ref และเมื่อมันชี้ไปยังโมเดลโรงพยาบาล ที่เชื่อมต่อ จะเรียก _roots_attach_signed_pdf_to_parent() ซึ่ง เขียน PDF ที่ประกอบเสร็จสุดท้ายลงใน roots_signed_pdf / roots_signed_pdf_filename ของ parent และโพสต์เป็นไฟล์แนบใน chatter

ไม่มีการเลื่อน state บน parent การลงนามเป็นแง่มุมที่ขนานกัน — inspection ยังคงเป็น submitted, contract ยังคงอยู่ใน state วงจรชีวิต ของตัวเอง (แผน §8 OQ3 + OQ2)

โมเดล: hemms.asset.inspection (_inherit) — เพิ่ม sign_request_ids (O2M), sign_request_count (stored compute), roots_signed_pdf (Binary, attachment=True), roots_signed_pdf_filename (Char), และ:

  • action_send_for_signature() — เรนเดอร์ PDF ปจป. สร้าง sign.oca.request พร้อมผู้ลงนาม 3 คน (ประธาน + กรรมการ 2 คน) ปฏิเสธหาก inspection ไม่ใช่ submitted หรือมีกรรมการคนใดที่หาตัวไม่ได้ (ไม่มี ผู้ใช้ Odoo ที่เชื่อมโยง)
  • action_view_sign_requests() — เปิดรายการที่เกี่ยวข้อง

โมเดล: hemms.service.contract (_inherit) — รูปแบบสะพานเดียวกัน: sign_request_ids, sign_request_count, roots_signed_pdf*, action_send_for_signature(), action_view_sign_requests()


HA Annual PM Report

roots_hemms_ha_report

โมเดล: hemms.ha.device.class — การจำแนก 82 device ของ MoPH seed เป็น noupdate="1" เพื่อให้การแก้ไขของโรงพยาบาลคงอยู่ผ่านการอัปเกรด ฟิลด์: name_th, name_en, risk_tier, pm_freq_months, pm_duration_hours, display_name (compute)

โมเดล: maintenance.equipment (_inherit) — ฟิลด์ waterfall ของ risk-tier:

ฟิลด์ ชนิด หมายเหตุ
device_class_id M2O hemms.ha.device.class ondelete='restrict'
roots_ha_risk_tier_override Selection การ override ของวิศวกรชนะใน waterfall
roots_ha_pm_freq_months_override Integer override ค่าเริ่มต้น 0 = สืบทอด
roots_em_function, roots_em_application, roots_em_maintenance, roots_em_history Integer สไลเดอร์ WHO Fennigkoh-Smith
roots_ha_risk_tier_effective Selection (compute) แก้ค่าผ่าน waterfall
roots_ha_pm_freq_months_effective Integer (compute) แก้ค่าผ่าน waterfall
roots_ha_risk_tier_source Selection ที่มา: override / device_class / em_score

โมเดล: hemms.ha.report — หนึ่งต่อ (department_id, fiscal_year_be) state machine: draft → in_progress → submitted → archived การลงนามขนานกัน (ไม่มี state signed แยก — ดู Q4 OQ3)

เมท็อด action สาธารณะ:

  • action_start()draftin_progress
  • action_submit()in_progresssubmitted สร้าง snapshot ที่แก้ไขไม่ได้ ผ่าน hemms.ha.report.snapshot._build_snapshot_payload(), ตรึงด้วย snapshot_id จากจุดนี้ การเขียนบรรทัดจะยก UserError (ดู _ensure_unlocked ในโมเดลบรรทัด)
  • action_archive_report()submittedarchived
  • action_send_for_signature() — ผู้ลงนาม 3 คน (BME Head, Engineering Head, Director) ปฏิเสธหากช่องผู้ลงนามใดว่างหรือไม่มี partner ที่เชื่อมโยง
  • action_reset_to_draft() — เฉพาะ Manager; ล้าง snapshot

โมเดล: hemms.ha.report.line — รายละเอียดต่อเครื่องมือแพทย์ ล็อกหลัง จาก parent submit helper _ensure_unlocked() ใน write/unlink ยก UserError เมื่อ parent ถูก submit แล้ว

โมเดล: hemms.ha.report.snapshot — snapshot JSON แบบ append-only _build_snapshot_payload() และ _build_paperformat_hash() เป็น helper สองตัวที่ QWeb (Q5.8) อ่านจาก template จะเรนเดอร์จาก snapshot สำหรับ report ที่ submitted/archived ใด ๆ เพื่อให้การพิมพ์ซ้ำ เหมือนกันทุก byte

จุดขยาย: sign.oca.request._check_signed() — ถูกขยายเป็น ครั้งที่สองที่นี่เพื่อจัดการ parent hemms.ha.report (เพิ่มเติมจาก inspection / contract ที่จัดการโดย Q4)

การสร้าง HA report

wizard = env["hemms.ha.report.generate"].create({
    "fiscal_year_be": "2569",
    "department_id": dept.id,
})
action = wizard.action_generate()    # opens the draft report
report = env["hemms.ha.report"].browse(action["res_id"])
report.action_start()
# ... engineer fills exception reasons on report.line_ids ...
report.action_submit()               # builds snapshot, locks lines
report.action_send_for_signature()   # spawns sign.oca.request

Mass import

roots_hemms_mass_import

โมเดล: hemms.import.batch — หนึ่งระเบียนต่อการอัปโหลด XLSX states: draft → previewed → committed → (archived | deleted)

ฟิลด์สำคัญ: name (running ref ผ่าน sequence), object_type (equipment / vendor / location), file_data (Binary), file_name (Char), data_json (Text — แถวที่ parse แล้ว + verdict ต่อแถว), committed_count, error_count, …

Service helper (import ได้):

  • services.parser — XLSX → list ของ dict
  • services.validator — ตรวจ business-key ต่อแถว (MoPH strict match, ฟิลด์ที่จำเป็น, …)
  • services.committer — commit แบบ transactional; เมื่อแถวล้มเหลวจะ ม้วนกลับทั้ง batch (แผน D14)
  • services.error_export — export XLSX ของแถวที่ผิดพลาด

ฟิลด์สะพานบนวัตถุที่ถูก import:

  • maintenance.equipment.roots_hemms_import_batch_id — M2O hemms.import.batch
  • res.partner.roots_hemms_import_batch_id
  • hr.department.roots_hemms_import_batch_id

สิ่งเหล่านี้ทำให้ _check_delete_blockers ของ batch ยืนยันได้ว่ามี ระเบียนที่ติดแท็กใดได้รับ PM event ปลายน้ำของ Q1 หรือสัญญาบริการ ของ Q3 หรือไม่ก่อนที่หน้าต่างลบ 7 วันจะปิดลง

ค่าคงที่:

  • OBJECT_MODEL{"equipment": "maintenance.equipment", "vendor": "res.partner", "location": "hr.department"}
  • DELETE_WINDOW_DAYS = 7

สูตร ORM ที่ใช้บ่อย

หาระดับความวิกฤตที่ใช้จริงของ request

def is_red_critical(request):
    # `roots_equipment_criticality_color` is a stored related — no SQL roundtrip.
    return request.roots_equipment_criticality_color == "red"

หา PM request ที่เปิดอยู่ทั้งหมดบนเครื่องมือแพทย์สีแดงที่ละเมิด SLA

env["maintenance.request"].search([
    ("maintenance_type", "=", "preventive"),
    ("roots_equipment_criticality_color", "=", "red"),
    ("roots_is_sla_breached", "=", True),
    ("stage_id.roots_is_done_stage", "=", False),
])

Submit การตรวจสอบจากโค้ด (เช่น สคริปต์ระหว่างการย้ายข้อมูล)

inspection = env["hemms.asset.inspection"].create({
    "department_id": dept.id,
    "fiscal_year_be": "2569",
    "chair_id": chair_emp.id,
    "committee_member_1_id": m1_emp.id,
    "committee_member_2_id": m2_emp.id,
})
# Add lines through the wizard or directly (line_ids o2m).
inspection.action_start_inspection()
# Set each line's condition.
inspection.action_submit()

ตรวจการตัดสินใจความครอบคลุมของสัญญาก่อนเรียกเก็บเงิน

contract = equipment.roots_active_contract_id
if not contract:
    bill_hospital()
    return
line = contract.coverage_line_ids.filtered(
    lambda L, k=kind: L.kind_id == k
)[:1]
if not line or not line.included_in_contract:
    bill_hospital()
elif line.billable_to_hospital:
    bill_hospital()
else:
    bill_vendor(contract.partner_id)

(ในทางปฏิบัติ คุณอ่าน maintenance_request.roots_is_billable_to_hospital โดยตรง — compute ด้านบนรันให้แล้ว)


  • สถาปัตยกรรม — โมเดล 3 ชั้นที่ API เหล่านี้อยู่ภายใน
  • การพัฒนาโมดูล — วิธีสร้างโมดูลใหม่ ที่ใช้ API เหล่านี้
  • CI/CD — ทำให้แน่ใจว่าการเปลี่ยนแปลงของคุณผ่านด่านเดียวกัน