Spaces:
Sleeping
Sleeping
Update main.py
Browse files
main.py
CHANGED
|
@@ -558,38 +558,58 @@ def _extract_sme_doc_text(filename: str, file_bytes: bytes) -> str:
|
|
| 558 |
|
| 559 |
return ""
|
| 560 |
|
| 561 |
-
|
| 562 |
-
def _fetch_active_programs(company_code: str) -> List[Dict[str, Any]]:
|
| 563 |
try:
|
| 564 |
-
|
| 565 |
-
|
| 566 |
-
|
| 567 |
-
.stream()
|
| 568 |
-
|
|
|
|
| 569 |
|
| 570 |
programs = []
|
|
|
|
| 571 |
for doc_snap in docs:
|
| 572 |
data = doc_snap.to_dict() or {}
|
| 573 |
status = _norm(data.get("status") or data.get("programStatus"))
|
|
|
|
| 574 |
if status and status not in ["active", "open", "running"]:
|
| 575 |
continue
|
| 576 |
|
|
|
|
|
|
|
| 577 |
programs.append({
|
| 578 |
"id": doc_snap.id,
|
| 579 |
-
"
|
|
|
|
| 580 |
"description": data.get("description") or "",
|
| 581 |
-
"
|
| 582 |
-
"
|
| 583 |
-
"
|
| 584 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 585 |
})
|
| 586 |
|
| 587 |
-
return programs[:
|
|
|
|
| 588 |
except Exception as e:
|
| 589 |
print("fetch_active_programs_failed:", e)
|
| 590 |
return []
|
| 591 |
|
| 592 |
-
|
| 593 |
def _fetch_intervention_catalog(company_code: str) -> List[Dict[str, Any]]:
|
| 594 |
try:
|
| 595 |
docs = (
|
|
@@ -717,7 +737,10 @@ Rules:
|
|
| 717 |
- urgent/high urgency should be used where compliance, tax, funding, payroll, legal, safety, or survival risks are clear.
|
| 718 |
- Recommend interventions only from the intervention catalog where possible.
|
| 719 |
- Recommend one program from availablePrograms where possible.
|
| 720 |
-
-
|
|
|
|
|
|
|
|
|
|
| 721 |
- benefitsOfProgram must explain why structured incubation helps.
|
| 722 |
- benefitsOfAgents must explain why direct agent support helps without programme onboarding.
|
| 723 |
- Keep text professional and concise.
|
|
@@ -1339,15 +1362,14 @@ def analyze_sme_application_intake():
|
|
| 1339 |
"""
|
| 1340 |
try:
|
| 1341 |
mode = request.form.get("mode") or "initial_review"
|
| 1342 |
-
company_code = request.form.get("companyCode")
|
| 1343 |
user_id = request.form.get("userId") or ""
|
| 1344 |
contact_name = request.form.get("contactName") or ""
|
| 1345 |
contact_email = request.form.get("email") or request.form.get("contactEmail") or ""
|
| 1346 |
contact_phone = request.form.get("contactPhone") or ""
|
| 1347 |
raw_story = (request.form.get("rawStory") or "").strip()
|
| 1348 |
|
| 1349 |
-
|
| 1350 |
-
return jsonify({"error": "Missing companyCode"}), 400
|
| 1351 |
|
| 1352 |
if not raw_story:
|
| 1353 |
return jsonify({"error": "Missing rawStory"}), 400
|
|
|
|
| 558 |
|
| 559 |
return ""
|
| 560 |
|
| 561 |
+
def _fetch_active_programs(company_code: Optional[str] = None) -> List[Dict[str, Any]]:
|
|
|
|
| 562 |
try:
|
| 563 |
+
ref = db.collection("programs")
|
| 564 |
+
|
| 565 |
+
if company_code:
|
| 566 |
+
docs = ref.where("companyCode", "==", company_code).stream()
|
| 567 |
+
else:
|
| 568 |
+
docs = ref.stream()
|
| 569 |
|
| 570 |
programs = []
|
| 571 |
+
|
| 572 |
for doc_snap in docs:
|
| 573 |
data = doc_snap.to_dict() or {}
|
| 574 |
status = _norm(data.get("status") or data.get("programStatus"))
|
| 575 |
+
|
| 576 |
if status and status not in ["active", "open", "running"]:
|
| 577 |
continue
|
| 578 |
|
| 579 |
+
eligibility = data.get("eligibilityCriteria") or {}
|
| 580 |
+
|
| 581 |
programs.append({
|
| 582 |
"id": doc_snap.id,
|
| 583 |
+
"companyCode": data.get("companyCode") or "",
|
| 584 |
+
"name": data.get("name") or "",
|
| 585 |
"description": data.get("description") or "",
|
| 586 |
+
"type": data.get("type") or "",
|
| 587 |
+
"cohortYear": data.get("cohortYear") or "",
|
| 588 |
+
"startDate": to_jsonable(data.get("startDate")),
|
| 589 |
+
"endDate": to_jsonable(data.get("endDate")),
|
| 590 |
+
"maxCapacity": data.get("maxCapacity"),
|
| 591 |
+
"registrationLink": data.get("registrationLink") or "",
|
| 592 |
+
"eligibilityCriteria": eligibility,
|
| 593 |
+
"eligibilitySummary": {
|
| 594 |
+
"minimumAge": eligibility.get("minimumAge"),
|
| 595 |
+
"maximumAge": eligibility.get("maximumAge"),
|
| 596 |
+
"gender": eligibility.get("gender"),
|
| 597 |
+
"sector": eligibility.get("sector"),
|
| 598 |
+
"province": eligibility.get("province"),
|
| 599 |
+
"minYearsOfTrading": eligibility.get("minYearsOfTrading"),
|
| 600 |
+
"bbbeeLevel": eligibility.get("bbbeeLevel"),
|
| 601 |
+
"minYouthOwnershipPercent": eligibility.get("minYouthOwnershipPercent"),
|
| 602 |
+
"minBlackOwnershipPercent": eligibility.get("minBlackOwnershipPercent"),
|
| 603 |
+
"minFemaleOwnershipPercent": eligibility.get("minFemaleOwnershipPercent"),
|
| 604 |
+
},
|
| 605 |
})
|
| 606 |
|
| 607 |
+
return programs[:50]
|
| 608 |
+
|
| 609 |
except Exception as e:
|
| 610 |
print("fetch_active_programs_failed:", e)
|
| 611 |
return []
|
| 612 |
|
|
|
|
| 613 |
def _fetch_intervention_catalog(company_code: str) -> List[Dict[str, Any]]:
|
| 614 |
try:
|
| 615 |
docs = (
|
|
|
|
| 737 |
- urgent/high urgency should be used where compliance, tax, funding, payroll, legal, safety, or survival risks are clear.
|
| 738 |
- Recommend interventions only from the intervention catalog where possible.
|
| 739 |
- Recommend one program from availablePrograms where possible.
|
| 740 |
+
- Match programmes using eligibilityCriteria first, especially province, sector, gender, age, years of trading, B-BBEE level, youth ownership, black ownership, and female ownership.
|
| 741 |
+
- If the SME does not clearly meet a programme's eligibility criteria, do not force that programme.
|
| 742 |
+
- If required eligibility data is missing from the SME story, add friendly questions to missingFields.
|
| 743 |
+
- If no programme fits, leave recommendedProgramId blank and explain why in summary.
|
| 744 |
- benefitsOfProgram must explain why structured incubation helps.
|
| 745 |
- benefitsOfAgents must explain why direct agent support helps without programme onboarding.
|
| 746 |
- Keep text professional and concise.
|
|
|
|
| 1362 |
"""
|
| 1363 |
try:
|
| 1364 |
mode = request.form.get("mode") or "initial_review"
|
| 1365 |
+
company_code = (request.form.get("companyCode") or "").strip()
|
| 1366 |
user_id = request.form.get("userId") or ""
|
| 1367 |
contact_name = request.form.get("contactName") or ""
|
| 1368 |
contact_email = request.form.get("email") or request.form.get("contactEmail") or ""
|
| 1369 |
contact_phone = request.form.get("contactPhone") or ""
|
| 1370 |
raw_story = (request.form.get("rawStory") or "").strip()
|
| 1371 |
|
| 1372 |
+
# companyCode is optional for public/unregistered SME intake
|
|
|
|
| 1373 |
|
| 1374 |
if not raw_story:
|
| 1375 |
return jsonify({"error": "Missing rawStory"}), 400
|