Add hiring, AI parser+admin, OTP auth, employer dashboard, profit-share pay
- Hiring (استخدام) listings: JobOpening + /Jobs browse/detail + home section - Heuristic Persian listing-parser + admin queue (/Admin) → publish shift/job - Phone-OTP cookie auth + visitor-history linking + profile; Admin role gate - Employer side: self-serve facility registration, dashboard, post/manage shifts & jobs, applicants list with contact - Compensation models: fixed / hourly / profit-share (درصدی) / negotiable / choice (به انتخاب شما); SharePercent + JalaliDate.PayLabel; parser + filter Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ public class ParsedListing
|
||||
public ShiftType? ShiftType { get; set; }
|
||||
public EmploymentType? EmploymentType { get; set; }
|
||||
public long? PayAmount { get; set; } // shift pay or single salary figure
|
||||
public int? SharePercent { get; set; } // profit-share % (درصدی / سهم درآمد)
|
||||
public bool PayNegotiable { get; set; }
|
||||
public string? CityName { get; set; }
|
||||
public string? DistrictName { get; set; }
|
||||
@@ -69,13 +70,22 @@ public class HeuristicListingParser : IListingParser
|
||||
p.DistrictName = knownDistricts.OrderByDescending(d => d.Length)
|
||||
.FirstOrDefault(d => text.Contains(Normalize(d)));
|
||||
|
||||
// --- Pay ---
|
||||
// --- Profit share (درصدی / سهم) ---
|
||||
var latinForShare = ToLatinDigits(text);
|
||||
var share = Regex.Match(latinForShare, @"(\d{1,3})\s*(?:٪|%|درصد)");
|
||||
if (!share.Success) share = Regex.Match(latinForShare, @"(?:٪|%)\s*(\d{1,3})");
|
||||
if (share.Success && int.TryParse(share.Groups[1].Value, out var pct) && pct is > 0 and <= 100)
|
||||
{ p.SharePercent = pct; p.Notes.Add($"سهم درآمد: {pct}٪"); }
|
||||
else if (ContainsAny(text, "درصدی", "سهم درآمد", "شراکت", "پورسانت"))
|
||||
{ p.Notes.Add("پرداخت درصدی/سهمی (درصد نامشخص)"); }
|
||||
|
||||
// --- Fixed pay ---
|
||||
if (ContainsAny(text, "توافقی", "توافق")) { p.PayNegotiable = true; p.Notes.Add("حقوق: توافقی"); }
|
||||
else
|
||||
{
|
||||
var amount = ExtractAmount(text);
|
||||
if (amount is not null) { p.PayAmount = amount; p.Notes.Add($"حقوق تخمینی: {amount:#,0} تومان"); }
|
||||
else p.Notes.Add("حقوق: تشخیص داده نشد");
|
||||
else if (p.SharePercent is null) p.Notes.Add("حقوق: تشخیص داده نشد");
|
||||
}
|
||||
|
||||
// --- Phone ---
|
||||
|
||||
Reference in New Issue
Block a user