سلام دوست عزیز😃👋

به «مسابقه هم‌کد ۶» خوش آمدی!

هرگونه ارتباط با سایر شرکت‌کنندگان و یا استفاده از ابزارهای تولید کد، مثل ChatGPT و... در مسابقات کوئرا ممنوع است و بعد از شناسایی از لیست شرکت‌کنندگان مسابقه حذف می‌شوید.

لینک‌های مفید برای شرکت در مسابقه:

سوالات و مشکلات خودتان را می‌توانید از طریق قسمت «سوال بپرسید» با ما در میان بگذارید.

  • چهار سوال اول مسابقه الگوریتمی است و سوال پنجم مهارت شما را در پیاده‌سازی به زبان Go می‌سنجد.
  • در سوالات الگوریتمی تنها در صورتی نمره‌ی آن را می‌گیرید که همه‌ی تست‌ها را بدون خطا پاسخ دهید و در غیر این‌صورت هیچ نمره‌ای از آن دریافت نمی‌کنید.

موفق باشید و بهتون خوش بگذره 😉✌

لیست سوالات را می‌توانید از نوار سمت راست این صفحه مشاهده کنید.

گیرینُف


تیم همکاران‌سیستم تصمیم گرفته سیستم ردیابی ساعات ورود و خروج خود را با قابلیت شخصی‌سازی برای تیم HR طراحی کند. همکاران که به‌شدت شرکت منظمی است و روی نظم کارمندان خود نیز حساس است از شما می‌خواهد برای ورود و استخدام به این شرکت و کمک به تیم منابع انسانی، بک‌اند سیستم ترکینگ ورود و خروج برنامه‌نویسان برای تهیه گزارش‌ها و محاسبه حقوق‌شان را پیاده‌سازی کنید.

جزئیات پروژه🔗

پروژه اولیه را از این لینک دانلود کنید. ساختار پروژه به شکل زیر است:

.
├── app
│   ├── db.go
│   ├── handlers.go   # TODO Implement
│   ├── models.go     # TODO Implement
│   ├── repository.go # TODO Implement
│   └── server.go
├── go.mod
├── go.sum
├── main.go
├── test
│   └── sample_test.go
Shell

در این پروژه، شما باید قسمت‌های مشخص شده با // TODO را پیاده‌سازی کنید. در نهایت شما از طریق اجرای فایل باینری main.go می‌توانید پروژه خود را اجرا کنید.

مدل‌های پایگاه‌داده🔗

ساختار جداول پروژه به شرح زیر باشد:

1- جدول Programmer

Column Name Type Notes
ID uint PRIMARY KEY AUTO_INCREMENT
Name string Programmer's name
CreatedAt time.Time Creation timestamp
UpdatedAt time.Time Last update timestamp

2- جدول Attendance

Column Name Type Notes
ID uint PRIMARY KEY AUTO_INCREMENT
ProgrammerID uint Foreign key to Programmer table
Date time.Time Attendance date
CheckIn time.Time Check-in time
CheckOut time.Time Check-out time
CreatedAt time.Time Creation timestamp
UpdatedAt time.Time Last update timestamp

روابط🔗

روابط بین مدل‌ها باید به شرح زیر پیاده‌سازی شوند:

  • هر برنامه‌نویس می‌تواند دارای چندین رکورد ورود و خروج باشد.
  • هر رکورد ورود و خروج متعلق به یک برنامه‌نویس است.
  • هر برنامه‌نویس در هر روز فقط باید یک رکورد ورود و خروج در سیستم ثبت نماید.

توابع Marshal/Unmarshal جیسون🔗

این توابع باید تبدیل صحیح بین JSON و ساختارهای Go برای مدل Attendance و AttendanceInput را مدیریت کنند:

func (a *Attendance) UnmarshalJSON(data []byte) error
func (a Attendance) MarshalJSON() ([]byte, error)
func (ai *AttendanceInput) UnmarshalJSON(data []byte) error
Go
متد UnmarshalJSON برای Attendance
func (a *Attendance) UnmarshalJSON(data []byte) error
Go
  • داده‌های JSON را به ساختار Attendance تبدیل می‌کند.

  • فیلدهای date، check_in و check_out از نوع رشته (string) دریافت می‌شوند و به نوع time.Time تبدیل می‌شوند.

  • فرمت‌های مورد انتظار:

    • date: YYYY-MM-DD

    • check_in: YYYY-MM-DD HH:MM:SS

    • check_out: YYYY-MM-DD HH:MM:SS

  • در صورت خطا در تبدیل فرمت‌ها، خطا برگردانده می‌شود.

خطاهای ممکن:

  • اگر date فرمت نامعتبر داشته باشد، خطای parsing time با پیام expected YYYY-MM-DD برگردانده می‌شود.

  • اگر check_in یا check_out فرمت نامعتبر داشته باشند، خطای parsing time با پیام expected YYYY-MM-DD HH:MM:SS برگردانده می‌شود.

مثال ورودی معتبر:

{
  "date": "2024-01-01",
  "check_in": "2024-01-01 09:00:00",
  "check_out": "2024-01-01 17:00:00",
  "programmer_id": 1
}
JSON

مثال ورودی نامعتبر:

{
  "date": "01-01-2024",
  "check_in": "09:00:00",
  "check_out": "2024-01-01 17:00:00",
  "programmer_id": 1
}
JSON
متد MarshalJSON برای Attendance
func (a Attendance) MarshalJSON() ([]byte, error)
Go
  • ساختار Attendance را به JSON تبدیل می‌کند.

  • فیلدهای date، check_in و check_out از نوع time.Time به رشته (string) تبدیل می‌شوند.

  • فرمت‌های خروجی:

    • date: YYYY-MM-DD در UTC

    • check_in: YYYY-MM-DD HH:MM:SS در UTC

    • check_out: YYYY-MM-DD HH:MM:SS در UTC

  • در صورت خطا در تبدیل، خطا برگردانده می‌شود.

مثال خروجی:

{
  "id": 1,
  "programmer_id": 1,
  "date": "2024-01-01",
  "check_in": "2024-01-01 09:00:00",
  "check_out": "2024-01-01 17:00:00"
}
JSON
متد UnmarshalJSON برای AttendanceInput
func (i *AttendanceInput) UnmarshalJSON(data []byte) error
Go
  • داده‌های JSON را به ساختار AttendanceInput تبدیل می‌کند.

  • فیلد date اجباری است و باید به فرمت YYYY-MM-DD باشد.

  • فیلدهای check_in و check_out اختیاری هستند و اگر وجود داشته باشند، باید به فرمت YYYY-MM-DD HH:MM:SS باشند.

  • در صورت خطا در تبدیل فرمت‌ها یا عدم وجود فیلد date، خطا برگردانده می‌شود.

خطاهای ممکن:

  • اگر date وجود نداشته باشد، خطای date field is necessary برگردانده می‌شود.

  • اگر date فرمت نامعتبر داشته باشد، خطای invalid date format, expected YYYY-MM-DD برگردانده می‌شود.

  • اگر check_in یا check_out فرمت نامعتبر داشته باشند، خطای invalid check_in/check_out format, expected YYYY-MM-DD HH:MM:SS برگردانده می‌شود.

مثال ورودی معتبر:

{
  "date": "2024-01-01",
  "check_in": "2024-01-01 09:00:00",
  "check_out": "2024-01-01 17:00:00"
}
JSON

مثال ورودی نامعتبر:

{
  "date": "2024/01/01",
  "check_in": "09:00:00"
}
JSON

نکته: برای یکتا بودن ProgrammerID و Date در Attendance می‌توانید از ایندکس کمک بگیرید.

هندلرها🔗

شما باید هندلرهای HTTP اندپوینت‌های زیر را با مشخصات دقیق آن‌ها که در ادامه بیان خواهد شد پیاده‌سازی کنید:

func RegisterRoutes(mux *http.ServeMux) {
    mux.HandleFunc("POST /attendance", CreateAttendanceHandler)
    mux.HandleFunc("GET /attendance/{programmer_id}", GetAttendanceHandler)
    mux.HandleFunc("PUT /attendance/{programmer_id}", UpdateAttendanceHandler)
    mux.HandleFunc("DELETE /attendance/{programmer_id}", DeleteAttendanceHandler)
    mux.HandleFunc("DELETE /attendance/{programmer_id}/{date}", DeleteOneDayAttendanceHandler)
    mux.HandleFunc("GET /attendance", GetAllAttendanceHandler)

    mux.HandleFunc("GET /girinof/{programmer_id}/{date}", GetGirinofReportHandler)
    mux.HandleFunc("GET /report/monthly/{programmer_id}/{start_date}/{end_date}", GetMonthlyReportHandler)
    mux.HandleFunc("GET /salary/{programmer_id}", GetSalaryHandler)

    mux.HandleFunc("POST /programmer", CreateProgrammerHandler)
}
Go
هندلر CreateAttendanceHandler

توضیح:

این هندلر برای ثبت حضور و غیاب برنامه‌نویسان است. ابتدا داده‌های ورودی را از ریکوئست دریافت کرده و اعتبار آن‌ها را بررسی می‌کند (مانند فرمت درست، وجود فیلد تاریخ، و ترتیب ورود و خروج). در صورت معتبر بودن، اطلاعات حضور را در سیستم ذخیره کرده و پاسخ مناسب ارسال می‌کند.

  • متد: POST
  • اندپوینت یا مسیر: /attendance
  • ورودی: بدنه JSON شامل:
{
  "programmer_id": uint,
  "date": "YYYY-MM-DD",
  "check_in": "YYYY-MM-DD HH:MM:SS",
  "check_out": "YYYY-MM-DD HH:MM:SS"
}
JSON

اعتبارسنجی:

  • در صورت دیکد نشدن JSON باید Invalid input format را با وضعیت 400 برگردانید.
  • در صورت عدم وجود فیلد تاریخ یا date باید Missing required field: date را با وضعیت 400 برگردانید.
  • در صورتی که ساعت خروج قبل از ساعت ورود بود، باید پیام CheckOut cannot be before CheckIn را با وضعیت 400 برگردانید.
  • در صورتی که programmer_id ارسال‌شده در پایگاه‌داده موجود نبود باید پیام Programmer not found! Please hire the programmer first. را با وضعیت 404 برگردانید.

پاسخ موفقیت‌آمیز:

  • وضعیت: 201 (ایجاد شده)
  • Content-Type: application/json
  • Body: شی attendance ایجاد شده

پاسخ خطا:

  • وضعیت: 500 با پیام Failed to create attendance: + پیام خطا (اگر رکوردی با همان programmer_id و date وجود داشته باشد، باید Duplicate attendance record را برگرداند که شما این مورد را در لایه‌ی ریپوزیتوری هندل می‌کنید)
هندلر GetAttendanceHandler

توضیح:

این هندلر برای دریافت سوابق حضور و غیاب یک برنامه‌نویس خاص است. ابتدا شناسه برنامه‌نویس را از مسیر URL استخراج کرده و اعتبارسنجی می‌کند. سپس، اگر داده‌ای موجود باشد، سوابق حضور را در قالب JSON برمی‌گرداند، در غیر این صورت پیام خطای مناسب ارسال می‌شود.

  • متد: GET

  • اندپوینت یا مسیر: /attendance/{programmer_id}

  • ورودی: programmer_id به عنوان پارامتر مسیر

اعتبارسنجی:

  • اگر programmer_id نامعتبر باشد (مثلاً عددی نباشد یا کمتر از ۱ باشد)، باید Invalid Programmer ID را با وضعیت 400 برگردانید.

  • اگر هیچ رکورد حضور و غیابی برای programmer_id داده‌شده وجود نداشته باشد، باید No attendance records found for the given Programmer ID را با وضعیت 404 برگردانید.

پاسخ موفقیت‌آمیز:

  • وضعیت: 200 (موفق)

  • Content-Type: application/json

  • Body: لیستی از رکوردهای حضور و غیاب مربوط به programmer_id

پاسخ خطا:

  • وضعیت: 500 با پیام Error retrieving attendance records + پیام خطا
هندلر UpdateAttendanceHandler

توضیح:

این هندلر برای به‌روزرسانی اطلاعات حضور و غیاب یک برنامه‌نویس است. ابتدا شناسه برنامه‌نویس و تاریخ موردنظر را بررسی کرده و در صورت وجود، اطلاعات جدید (مانند ورود و خروج) را ثبت می‌کند. اگر داده‌ای نامعتبر باشد یا رکورد حضور قبلاً ثبت نشده باشد، پیام خطای مناسب ارسال می‌شود.

  • متد: PUT

  • اندپوینت یا مسیر: /attendance/{programmer_id}

  • ورودی: بدنه JSON دو فیلد ورود و خروج به صورت اختیاری:

{
  "date": "YYYY-MM-DD",
  "check_in": "YYYY-MM-DD HH:MM:SS",
  "check_out": "YYYY-MM-DD HH:MM:SS"
}
JSON

اعتبارسنجی:

  • اگر programmer_id نامعتبر باشد (مثلاً عددی نباشد یا کمتر از ۱ باشد)، باید Invalid Programmer ID" را با وضعیت 400 برگردانید.

  • اگر programmer_id در دیتابیس وجود نداشته باشد، باید Programmer not found را با وضعیت 404 برگردانید.

  • اگر فیلد date یا programmer_id ارسال نشوند باید پیام Programmer ID is required و Date is required با وضعیت 400 برگردانید.

  • اگر date ارسال‌شده برای programmer_id موجود نباشد، باید Programmer with the given date not recorded. Please use CreateAttendanceHandler to create it! را با وضعیت 400 برگردانید.

  • اگر تاریخ خروج قبل از تاریخ ورود باشد، باید CheckIn cannot be after CheckOut را با وضعیت 400 برگردانید.

پاسخ موفقیت‌آمیز:

  • وضعیت: 200 (موفق)
  • Content-Type: application/json
  • Body: گزارش GirinofReport به شکل زیر:
{
  "programmer_id": "1",
  "total_delays": 2,
  "total_early_departures": 3
}
JSON

پاسخ خطا:

  • وضعیت: 500 با پیام Failed to update attendance + پیام خطا
هندلر DeleteAttendanceHandler

توضیح:

این هندلر برای حذف سوابق حضور و غیاب یک برنامه‌نویس است. ابتدا شناسه برنامه‌نویس را بررسی کرده و در صورت معتبربودن، رکورد یا رکوردهای حضور مربوطه را حذف می‌کند. در صورت نامعتبربودن شناسه یا بروز خطا، پیام خطای مناسب ارسال می‌شود.

  • متد: DELETE

  • اندپوینت یا مسیر: /attendance/{programmer_id}

  • ورودی: programmer_id به عنوان پارامتر مسیر

اعتبارسنجی:

  • اگر programmer_id نامعتبر باشد (مثلاً عددی نباشد یا کمتر از ۱ باشد)، باید Invalid programmer ID را با وضعیت 400 برگردانید.

  • اگر برنامه‌نویسی با آیدی متناظر با programmer_id موجود نباشد، باید Programmer not found را با وضعیت 404 برگردانید.

  • اگر date در قالب YYYY-MM-DD نباشد، باید Invalid date format را با وضعیت 400 برگرداند. (این مورد را در بخش توابع Marshal/Unmarshal جیسون هندل می‌کنید)

پاسخ موفقیت‌آمیز:

  • وضعیت: 202 (پذیرفته‌شده)

پاسخ خطا:

  • وضعیت: 500 با پیام Failed to delete attendance + پیام خطا
هندلر DeleteOneDayAttendanceHandler

توضیح:

این هندلر برای حذف سوابق حضور و غیاب یک برنامه‌نویس در یک تاریخ مشخص است. ابتدا شناسه برنامه‌نویس و تاریخ را از مسیر URL دریافت کرده و بررسی می‌کند. در صورت معتبربودن و وجود رکورد، آن را حذف می‌کند؛ در غیر این صورت، پیام خطای مناسب ارسال می‌شود.

  • متد: DELETE

  • اندپوینت یا مسیر: /attendance/{programmer_id}/{date}

  • ورودی:

    • programmer_id به عنوان پارامتر مسیر

    • date به عنوان پارامتر مسیر (فرمت: YYYY-MM-DD)

اعتبارسنجی:

  • اگر programmer_id نامعتبر باشد (مثلاً عددی نباشد یا کمتر از ۱ باشد)، باید Invalid programmer ID را با وضعیت 400 برگردانید.

  • اگر date فرمت نامعتبر داشته باشد، باید Invalid Date را با وضعیت 400 برگردانید.

  • اگر programmer_id یا date مورد نظر وجود نداشت، باید No attendance record found for the given date با وضعیت 404 را بازگردانید.

پاسخ موفقیت‌آمیز:

  • وضعیت: 202 (پذیرفته‌شده)

پاسخ خطا:

  • وضعیت: 500 با پیام Failed to delete attendance + پیام خطا
هندلر GetAllAttendanceHandler

توضیح:

این هندلر برای دریافت تمامی سوابق حضور و غیاب است. ابتدا تمام داده‌های حضور را از پایگاه‌داده واکشی کرده و در قالب JSON بازمی‌گرداند. در صورت بروز خطا در دریافت اطلاعات، پیام خطای مناسب ارسال می‌شود.

  • متد: GET

  • اندپوینت یا مسیر: /attendance

  • ورودی: ندارد

اعتبارسنجی:

  • نیاز به اعتبارسنجی خاصی ندارد (همه رکوردها را برمی‌گرداند)

پاسخ موفقیت‌آمیز:

  • وضعیت: 200 (موفق)

  • Content-Type: application/json

  • Body: لیست کامل تمامی رکوردهای حضور و غیاب

پاسخ خطا:

  • وضعیت: 500 با پیام Failed to fetch attendance records + پیام خطا
هندلر GetGirinofReportHandler

توضیح:

این هندلر برای دریافت گزارش حضور و غیاب یک برنامه‌نویس در یک تاریخ مشخص است. ابتدا شناسه برنامه‌نویس و تاریخ را بررسی کرده و در صورت وجود اطلاعات، گزارش را تولید و در قالب JSON بازمی‌گرداند. در صورت عدم وجود داده یا خطای پردازش، پیام خطای مناسب ارسال می‌شود.

  • متد: GET

  • اندپوینت یا مسیر: /girinof/{programmer_id}/{date}

  • ورودی:

    • programmer_id به عنوان پارامتر مسیر

    • date به عنوان پارامتر مسیر (فرمت: YYYY-MM-DD)

اعتبارسنجی:

  • اگر programmer_id ارسال‌ نشده باشد، باید Programmer ID is required را با وضعیت 400 برگرداند.
  • اگر date ارسال‌ نشده باشد، باید Date is required را با وضعیت 400 برگرداند.
  • اگر date فرمت نامعتبر داشته باشد، باید Invalid Date را با وضعیت 400 برگرداند.
  • اگر programmer_id عدد نباشد یا کمتر از ۱ باشد، باید Invalid Programmer ID را با وضعیت 400 برگرداند.
  • اگر برنامه‌نویس با programmer_id داده‌شده وجود نداشته باشد، باید Programmer not found را با وضعیت 404 برگرداند.
  • اگر رکورد حضور برای programmer_id و date داده‌شده وجود نداشته باشد، باید Programmer with the given date not recorded. Please use CreateAttendanceHandler to create it! را با وضعیت 400 برگرداند.

پاسخ موفقیت‌آمیز:

  • وضعیت: 200 (موفق)

  • Content-Type: application/json

  • Body: گزارش GirinofReport

  • محاسبات باید بر اساس اختلاف زمانی با ساعت استاندارد (۹:۰۰-۱۷:۰۰) انجام شود.

پاسخ خطا:

  • وضعیت: 500 با پیام Failed to generate report + پیام خطا
هندلر GetMonthlyReportHandler

توضیح:

این هندلر برای دریافت گزارش حضور و غیاب یک برنامه‌نویس در یک بازه زمانی مشخص است. ابتدا شناسه برنامه‌نویس، تاریخ شروع و پایان را بررسی کرده و در صورت معتبر بودن، گزارش را تولید و در قالب JSON بازمی‌گرداند. در صورت نامعتبر بودن ورودی‌ها یا بروز خطا، پیام خطای مناسب ارسال می‌شود.

  • متد: GET

  • اندپوینت یا مسیر: /report/monthly/{programmer_id}/{start_date}/{end_date}

  • ورودی:

    • programmer_id به عنوان پارامتر مسیر

    • start_date و end_date به عنوان پارامتر مسیر (فرمت: YYYY-MM-DD)

اعتبارسنجی:

  • اگر programmer_id ارسال‌ نشده باشد، باید Programmer ID is required را با وضعیت 400 برگرداند.
  • اگر start_date یا end_date ارسال‌ نشده باشد، باید Start date is required یا End date is required را با وضعیت 400 برگرداند.
  • اگر programmer_id عدد نباشد یا کمتر از ۱ باشد، باید Invalid programmer ID را با وضعیت 400 برگرداند.
  • اگر start_date یا end_date فرمت نامعتبر داشته باشند، باید Invalid start date format یا Invalid end date format را با وضعیت 400 برگرداند.
  • اگر end_date قبل از start_date باشد، باید End date cannot be before start date را با وضعیت 400 برگرداند.
  • اگر برنامه‌نویس با programmer_id داده‌شده وجود نداشته باشد، باید Programmer not found را با وضعیت 404 برگرداند.

پاسخ موفقیت‌آمیز:

  • وضعیت: 200 (موفق)

  • Content-Type: application/json

  • Body: گزارش MonthlySummary به شکل زیر:

{
  "programmer_id": "1",
  "total_days_present": 4,
  "total_overtime_minutes": 3,
  "total_delay_minutes": 2,
  "total_early_departure_minutes": 1
}
JSON
  • محاسبات باید بر اساس اختلاف زمانی با ساعت استاندارد (۹:۰۰-۱۷:۰۰) انجام شود.

پاسخ خطا:

  • وضعیت: 500 با پیام Failed to generate monthly report + پیام خطا
هندلر GetSalaryHandler

توضیح:

این هندلر برای محاسبه حقوق یک برنامه‌نویس در ۳۰ روز گذشته است. ابتدا شناسه برنامه‌نویس را بررسی کرده و در صورت معتبربودن، حقوق او را بر اساس سوابق حضور و غیاب محاسبه و در قالب JSON بازمی‌گرداند. در صورت عدم وجود اطلاعات یا بروز خطا، پیام خطای مناسب ارسال می‌شود.

  • متد: GET

  • اندپوینت یا مسیر: /salary/{programmer_id}

  • ورودی: programmer_id به عنوان پارامتر مسیر

اعتبارسنجی:

  • اگر programmer_id ارسال‌ نشده باشد، باید Programmer ID is required را با وضعیت 400 برگرداند.
  • اگر programmer_id عدد نباشد یا کمتر از ۱ باشد، باید Invalid programmer ID را با وضعیت 400 برگرداند.
  • اگر برنامه‌نویس با programmer_id داده‌شده وجود نداشته باشد، باید Programmer not found را با وضعیت 404 برگرداند.

پاسخ موفقیت‌آمیز:

  • وضعیت: 200 (موفق)

  • Content-Type: application/json

  • Body: گزارش SalaryReport به شکل زیر:

{
  "name": "Younes Sinwar",
  "total_days_present": 30,
  "total_overtime_minutes": 1,
  "total_delay_minutes": 2,
  "total_early_departure_minutes": 3,
  "total_salary": 3000.0
}
JSON
  • محاسبات باید بر اساس اختلاف زمانی با ساعت استاندارد (۹:۰۰-۱۷:۰۰) انجام شود.

محاسبه حقوق: حقوق بر اساس فرمول زیر محاسبه می‌شود:

حقوق پایه = تعداد روزهای حضور × DailyRate (۱۰۰)

اضافه‌کاری = مجموع دقیقه‌های اضافه‌کاری × OvertimeRate (۲۰)

جریمه تاخیر = مجموع دقیقه‌های تاخیر × DelayPenalty (۱۰)

حقوق نهایی = حقوق پایه + اضافه‌کاری - جریمه تاخیر
Plain text

پاسخ خطا:

  • وضعیت: 500 با پیام Failed to calculate salary + پیام خطا
هندلر CreateProgrammerHandler

توضیح:

این هندلر برای ایجاد یک برنامه‌نویس جدید در سیستم است. ابتدا داده‌های ورودی را بررسی کرده و در صورت معتبربودن، برنامه‌نویس را در پایگاه‌داده ثبت می‌کند. در صورت بروز خطا یا نامعتبربودن اطلاعات، پیام خطای مناسب ارسال می‌شود.

  • متد: POST

  • اندپوینت یا مسیر: /programmer

  • ورودی: بدنه JSON شامل:

{
  "name": "string"
}
JSON

اعتبارسنجی:

  • اگر name ارسال‌ نشده باشد، باید Invalid input format را با وضعیت 400 برگردانید.
    • اگر فیلد name خالی باشد، باید Name is required را با وضعیت 400 برگردانید.

پاسخ موفقیت‌آمیز:

  • وضعیت: 201 (ایجاد شده)

  • Content-Type: application/json

  • Body: شی programmer ایجادشده

پاسخ خطا:

  • وضعیت: 500 با پیام Failed to create programmer + پیام خطا
  • در تمام هندلرها اگر خطای داخلی سرور رخ دهد، باید وضعیت 500 برگردانده شود.

توابع Repository🔗

متدهای Repository زیر را پیاده‌سازی کنید:

func (repo *Repository) CreateAttendance(attendance *Attendance) error
func (repo *Repository) GetAttendancesByProgrammer(pid uint) ([]Attendance, error)
func (repo *Repository) GetAllAttendance() ([]Attendance, error)
func (repo *Repository) UpdateAttendance(attendance *Attendance) error
func (repo *Repository) DeleteAttendance(pid uint) error
func (repo *Repository) DeleteOneDayAttendance(pid uint, date time.Time) error
func (repo *Repository) GetGirinofReport(pid uint, date time.Time) (*GirinofReport, error)
func (repo *Repository) GetMonthlyReport(pid uint, startDate, endDate time.Time) (*MonthlySummary, error)
func (repo *Repository) CalculateSalary(pid uint, startDate, endDate time.Time) (*SalaryReport, error)
func (repo *Repository) CreateProgrammer(name string) (*Programmer, error)
func (repo *Repository) GetProgrammerByID(id uint) (*Programmer, error)
func (repo *Repository) IsExistDateAndProgrammerID(id uint, date time.Time) (*Attendance, bool)
Go
متد CreateAttendance
func (repo *Repository) CreateAttendance(attendance *Attendance) error
Go
  • رکورد Attendance جدیدی با تمام فیلدهای الزامی ایجاد می‌کند

  • در صورت وجود attendance تکراری (با همان ProgrammerID و Date) خطا برمی‌گرداند

  • آی‌دی تولید شده برای رکورد جدید باید غیرصفر باشد

  • در صورت خطا در عملیات پایگاه‌داده، خطا را برمی‌گرداند

متد GetAttendancesByProgrammer

‍‍‍

func (repo *Repository) GetAttendancesByProgrammer(pid uint) ([]Attendance, error)
Go
  • لیست تمام رکوردهای حضور و غیاب یک برنامه‌نویس را برمی‌گرداند

  • نتایج باید بر اساس تاریخ (date) به صورت نزولی مرتب شوند

  • حداکثر ۱۲ رکورد بازگردانده شود

  • در صورت عدم وجود رکورد، لیست خالی برمی‌گرداند

  • در صورت خطا در عملیات پایگاه‌داده، خطا را برمی‌گرداند

متد GetAllAttendance
func (repo *Repository) GetAllAttendance() ([]Attendance, error)
Go
  • لیست تمامی رکوردهای حضور و غیاب موجود در پایگاه‌داده را برمی‌گرداند.

  • در صورت عدم وجود رکورد، لیست خالی برمی‌گرداند.

  • در صورت خطا، خطا را برمی‌گرداند.

متد UpdateAttendance
func (repo *Repository) UpdateAttendance(attendance *Attendance) error
Go
  • رکورد موجود را با مقادیر جدید به‌روزرسانی می‌کند.

  • فیلدهای قابل به‌روزرسانی: date، check_in و check_out

  • در صورت عدم وجود رکورد مرتبط، خطا برمی‌گرداند.

  • در صورت خطا در عملیات پایگاه‌داده، خطا را برمی‌گرداند.

متد DeleteAttendance
func (repo *Repository) DeleteAttendance(pid uint) error
Go
  • تمام رکوردهای حضور و غیاب مربوط به یک برنامه‌نویس را حذف می‌کند.

  • پس از حذف، هیچ رکوردی با ProgrammerID مربوطه نباید وجود داشته باشد.

  • در صورت خطا در عملیات پایگاه‌داده، خطا را برمی‌گرداند.

متد DeleteOneDayAttendance
func (repo *Repository) DeleteOneDayAttendance(pid uint, date time.Time) error
Go
  • رکورد حضور و غیاب مربوط به یک روز خاص را حذف می‌کند.

  • تاریخ باید دقیقاً مطابقت داشته باشد (برای انجام این کار تمامی رکوردهای تاریخ آن روز را از ساعت 00:00:00 تا ساعت 24:00:00 حذف کنید. می‌توانید از date.Truncate استفاده کنید)

  • در صورت عدم وجود رکورد، خطا برمی‌گرداند.

  • در صورت خطا در عملیات پایگاه‌داده، خطا را برمی‌گرداند.

متد GetGirinofReport
func (repo *Repository) GetGirinofReport(pid uint, date time.Time) (*GirinofReport, error)
Go
  • گزارش روزانه شامل مجموع تاخیرها (total_delay_minutes) و خروج‌های زودهنگام (total_early_departure_minutes) را همراه با programmer_id ایجاد می‌کند.

  • محاسبات باید بر اساس اختلاف زمانی با ساعت استاندارد (۹:۰۰-۱۷:۰۰) انجام شود.

  • در صورت عدم وجود رکورد در تاریخ مشخص، خطا برمی‌گرداند.

  • در صورت خطا در محاسبات یا عملیات پایگاه‌داده، خطا را برمی‌گرداند.

متد GetMonthlyReport
func (repo *Repository) GetMonthlyReport(id string, startDate, endDate time.Time) (*MonthlySummary, error)
Go
  • گزارش ماهانه شامل آمار حضور، اضافه‌کاری و تاخیرها را در بازه زمانی داده شده ایجاد می‌کند

  • محاسبات باید بر اساس اختلاف زمانی با ساعت استاندارد (۹:۰۰-۱۷:۰۰) انجام شود.

  • این گزارش شامل آی‌دی برنامه‌نویس (programmer_id) تعداد روزهای حضور (total_days_present)، مجموع دقیقه‌های اضافه‌کاری (total_overtime_minutes)، مجموع دقیقه‌های تاخیر (total_delay_minutes) و مجموع دقیقه‌های خروج زودهنگام (total_early_departure_minutes) است.

  • در صورت خطا در محاسبات یا عملیات پایگاه‌داده، خطا را برمی‌گرداند.

متد CalculateSalary
func (repo *Repository) CalculateSalary(id string, startDate, endDate time.Time) (*SalaryReport, error)
Go
  • حقوق (SalaryReport) یک برنامه‌نویس خاص را در سی روز گذشته محاسبه می‌کند.

  • محاسبات باید بر اساس اختلاف زمانی با ساعت استاندارد (۹:۰۰-۱۷:۰۰) انجام شود.

  • حقوق خالص را بر اساس فرمول زیر محاسبه می‌کند:

    • حقوق پایه = تعداد روزهای حضور × نرخ روزانه (DailyRate)

    • اضافه‌کاری = مجموع دقیقه‌های اضافه‌کاری × نرخ اضافه‌کاری (OvertimeRate)

    • جریمه تاخیر = مجموع دقیقه‌های تاخیر × نرخ جریمه (DelayPenalty)

    • حقوق نهایی = حقوق پایه + اضافه‌کاری - جریمه تاخیر

  • این گزارش شامل نام برنامه‌نویس (name)، تعداد روزهای حضور (total_days_present)، مجموع دقیقه‌های اضافه‌کاری (total_overtime_minutes)، مجموع دقیقه‌های تاخیر (total_delay_minutes)، مجموع دقیقه‌های خروج زودهنگام (total_early_departure_minutes) و مجموع حقوق (total_salary) است.

  • در صورت خطا در محاسبات یا عملیات پایگاه‌داده، خطا را برمی‌گرداند

متد CreateProgrammer
func (repo *Repository) CreateProgrammer(name string) (*Programmer, error)
Go
  • یک برنامه‌نویس جدید ایجاد می‌کند.
  • آی‌دی تولید شده باید غیرصفر باشد.
  • در صورت خطا در عملیات پایگاه‌داده، خطا را برمی‌گرداند.
متد GetProgrammerByID
func (repo *Repository) GetProgrammerByID(id uint) (*Programmer, error)
Go
  • اطلاعات کامل برنامه‌نویس را بر اساس ID برمی‌گرداند.

  • در صورت عدم وجود برنامه‌نویس با ID داده شده، خطا برمی‌گرداند.

  • در صورت خطا در عملیات پایگاه‌داده، خطا را برمی‌گرداند.

متد IsExistDateAndProgrammerID
func (repo *Repository) IsExistDateAndProgrammerID(id uint, date time.Time) (*Attendance, bool)
Go
  • بررسی می‌کند که آیا رکورد حضور و غیاب برای یک برنامه‌نویس خاص در تاریخ مشخص وجود دارد یا خیر.

  • تاریخ باید دقیقاً مطابقت داشته باشد (برای انجام این کار تمامی رکوردهای تاریخ آن در آن روز یعنی از ساعت 00:00:00 تا ساعت 24:00:00 را بررسی کنید)

  • در صورت وجود، رکورد کامل را همراه با true برمی‌گرداند.

  • در صورت عدم وجود، nil و false برمی‌گرداند.

  • تاریخ باید دقیقاً مطابقت داشته باشد (با در نظر گرفتن ساعت ۰۰:۰۰:۰۰)

نکات

  • شما باید در این سوال از GORM و ویژگی‌های آن استفاده کنید و به جز پکیج‌های موجود در پروژه اولیه اجازه استفاده از پکیج دیگری را ندارید.

  • فایل db.go برای اتصال GORM به پایگاه‌داده با استفاده از الگوی طراحی singleton است. شما نیازی به تغییر آن ندارید به جز تغییر ثابت‌ها برای تست روی محیط لوکال خود.

  • فایل‌ها و کدهای پروژه‌اولیه را نباید تغییر بدهید و صرفا باید مکان‌هایی که با کامنت // TODO Implement برای شما مشخص شده را پیاده‌سازی کنید.

  • نیازی به ارسال فایل‌های go.mod و go.sum ندارید!

چه چیزی را آپلود کنید

پس از پیاده‌سازی ویژگی‌های خواسته‌شده،‌ فقط دایرکتوری app که شامل سه فایل handlers.go و models.go و repository.go است را فشرده کرده و صورت زیپ ارسال کنید. فایل‌هایی که نیاز به ویرایش دارند:

  • app/models.go‍
  • app/handlers.go
  • app/repository.go
ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.