دو شغله


  • محدودیت زمان: ۱ ثانیه
  • محدودیت حافظه: ۲۵۶ مگابایت

علی که خیلی به کسب و کار اهمیت می‌دهد به تازگی در دو بانک کار می‌کند. او باید روزهای زوج به بانک «پرسپولیس» و روزهای فرد به بانک «بهمن» برود.

می‌دانیم روزهای «شنبه»، «دوشنبه» و «چهارشنبه» یک روز زوج و روزهای «یک‌شنبه»، «سه‌شنبه» و «پنج‌شنبه» یک روز فرد است. همچنین روز «جمعه» تعطیل است.

به شما یک رشته داده می‌شود که یکی از روزهای هفته را نشان می‌دهد. از شما می‌خواهیم نام بانکی که علی باید در آن روز، آن‌جا کار کند را چاپ کنید یا این‌که اعلام کنید این روز تعطیل است.

  • شنبه (shanbe) یک روز زوج است، پس باید در بانک پرسپولیس (perspolis) کار کند.
  • یک‌شنبه (yekshanbe) یک روز فرد است، پس باید در بانک بهمن (bahman) کار کند.
  • دوشنبه (doshanbe) یک روز زوج است، پس باید در بانک پرسپولیس (perspolis) کار کند.
  • سه‌شنبه (seshanbe) یک روز فرد است، پس باید در بانک بهمن (bahman) کار کند.
  • چهارشنبه (chaharshanbe) یک روز زوج است، پس باید در بانک پرسپولیس (perspolis) کار کند.
  • پنج‌شنبه (panjshanbe) یک روز فرد است، پس باید در بانک بهمن (bahman) کار کند.
  • جمعه (jome) یک روز تعطیل (tatil) است و لازم نیست جایی کار کند.

ورودی🔗

در تنها سطر ورودی یکی از ۷ رشته shanbe، yekshanbe، doshanbe، seshanbe، chaharshanbe، panjshanbe یا jome داده می‌شود.

خروجی🔗

در تنها سطر خروجی در صورتی که روز کار در بانک پرسپولیس است perspolis و در صورتی که روز کار در بانک بهمن است bahman و در صورت تعطیل بودن tatil را چاپ کنید.

مثال🔗

ورودی نمونه ۱🔗

shanbe
Plain text

خروجی نمونه ۱🔗

perspolis
Plain text

شنبه یک روز زوج است، پس باید در بانک «پرسپولیس» کار کند.

ورودی نمونه ۲🔗

seshanbe
Plain text

خروجی نمونه ۲🔗

bahman
Plain text

سه‌شنبه یک روز فرد است، پس باید در بانک «بهمن» کار کند.

ورودی نمونه ۳🔗

jome
Plain text

خروجی نمونه ۳🔗

tatil
Plain text

جمعه یک روز تعطیل است و نیازی نیست جایی کار کند.

تبدیل ارز


  • محدودیت زمان: ۱ ثانیه
  • محدودیت حافظه: ۲۵۶ مگابایت

علی به سه کشور امارات، فرانسه و آمریکا سفر کرده و به تازگی به ایران برگشته است.

او برای هزینه‌های این سفر از دوستش محمد nn ریال قرض گرفته بود و حالا که از سفر برگشته می‌خواهد این قرض را به محمد پس بدهد.

علی با خود xx اسکناس یک درهمی از امارات، yy اسکناس یک یورویی از فرانسه و zz اسکناس یک دلاری از آمریکا آورده است.

می‌دانیم در روز پرداخت، قیمت یک درهم aa ریال، قیمت یک یورو bb ریال و قیمت یک دلار cc ریال است.

علی می‌خواهد بداند به چند طریق می‌تواند xx' اسکناس یک درهمی، yy' اسکناس یک یورویی، zz' اسکناس یک دلاری به محمد بدهد به طوری که ارزش آن‌ها دقیقاً nn ریال باشد.

به عبارت دیگر تعداد راه‌های مشخص کردن سه عدد صحیح xx'، yy' و zz' به طوری که: x×a+y×b+z×c=nx' \times a + y' \times b + z' \times c = n 0xx,0yy,0zz0 \le x' \le x, \quad 0 \le y' \le y, \quad 0 \le z' \le z چقدر است؟

ورودی🔗

در سطر اول ورودی تنها عدد صحیح nn آمده که نشان‌دهنده مبلغی (به ریال) است که علی باید به محمد پرداخت کند. 1n1000001 \le n \le 100\,000 در سطر دوم ورودی سه عدد صحیح xx، yy و zz با فاصله آمده که به ترتیب نشان‌دهنده تعداد اسکانس‌های درهم، یورو و دلار است. 0x,y,z50000 \le x, y, z \le 5000 در سطر سوم ورودی سه عدد صحیح aa، bb و cc با فاصله آمده که به ترتیب نشان‌دهنده قیمت یک درهم، یورو و دلار بر حسب ریال است. 1a,b,c1000001 \le a, b, c \le 100\,000

خروجی🔗

در تنها سطر خروجی یک عدد صحیح که نشان‌دهنده پاسخ مسئله یعنی تعداد روش‌های پرداخت nn ریال به محمد است را چاپ کنید.

مثال🔗

ورودی نمونه ۱🔗

100000
2 1 1
50000 70000 30000
Plain text

خروجی نمونه ۱🔗

2
Plain text

دو روش برای پرداخت ممکن است:

  • دو اسکناس یک درهمی بدهد. 2×50000+0×70000+0×30000=1000002 \times 50\,000 + 0 \times 70\,000 + 0 \times 30\,000 = 100\,000
  • یک اسکناس یک یورویی و یک اسکناس یک دلاری بدهد. 0×50000+1×70000+1×30000=1000000 \times 50\,000 + 1 \times 70\,000 + 1 \times 30\,000 = 100\,000

ورودی نمونه ۲🔗

60000
3 3 3
30000 20000 30000
Plain text

خروجی نمونه ۲🔗

4
Plain text

چهار روش برای پرداخت ممکن است:

  • دو اسکناس یک درهمی بدهد. 2×30000+0×20000+0×30000=600002 \times 30\,000 + 0 \times 20\,000 + 0 \times 30\,000 = 60\,000
  • دو اسکناس یک دلاری بدهد. 0×30000+0×20000+2×30000=600000 \times 30\,000 + 0 \times 20\,000 + 2 \times 30\,000 = 60\,000
  • یک اسکناس یک درهمی و یک اسکناس یک دلاری بدهد. 1×30000+0×20000+1×30000=600001 \times 30\,000 + 0 \times 20\,000 + 1 \times 30\,000 = 60\,000
  • سه اسکناس یک یورویی بدهد. 0×30000+3×20000+0×30000=600000 \times 30\,000 + 3 \times 20\,000 + 0 \times 30\,000 = 60\,000

ورودی نمونه ۳🔗

32000
2 1 1
4200 7500 3600
Plain text

خروجی نمونه ۳🔗

0
Plain text

مجموع ارزش پولی که علی دارد کمتر از پولی است که باید به محمد بدهد. 2×4200+1×7500+1×3600=19500<320002 \times 4\,200 + 1 \times 7\,500 + 1 \times 3\,600 = 19\,500 < 32\,000 پس هیچ راهی برای پرداخت ندارد.

دیجی‌والِت


محمدرضا و تیمش مشغول طراحی سامانه‌ای برای مدیریت کیف پول دیجیتال به‌نام دیجی‌والِت هستند. در نسخه‌ی اولیه‌ی این سامانه قرار است قابلیت‌های زیر وجود داشته باشد:

  • امکان ایجاد تراکنش و تغییر وضعیت آن
  • امکان مشاهده‌ی لیست تراکنش‌ها
  • امکان تسویه‌حساب
  • امکان مشاهده‌ی موجودی کیف پول

تیم محمدرضا ساختار برنامه را طراحی کرده‌اند و از شما می‌خواهند تا پیاده‌سازی آن را انجام دهید.

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

پروژه‌ی اولیه را از این لینک دانلود کنید.

ساختار فایل‌ها
src
└── ir
    └── digipay
        └── digiwallet
            ├── model
            │   ├── AdminWallet.java
            │   ├── Transaction.java
            │   ├── TransactionStatus.java
            │   ├── TransactionType.java
            │   └── Wallet.java
            ├── repository
            │   ├── CrudRepository.java
            │   ├── TransactionRepository.java
            │   └── TransactionRepositoryImpl.java
            ├── service
            │   ├── AdminWalletService.java
            │   └── WalletService.java
            ├── Application.java
            └── DigiWalletSampleTest.java
Plain text

مدل‌ها🔗

  • کیف پول (Wallet)
    • این مدل تنها شامل یک شناسه از نوع String است.
  • کیف پول مربوط به ادمین‌های برنامه (AdminWallet)
    • این مدل از کلاس Wallet ارث‌بری می‌کند و هیچ پیاده‌سازی اضافه‌ای نسبت به مدل Wallet ندارد.
  • نوع تراکنش (TransactionType): این کلاس یک enum است که به‌ترتیب شامل دو مقدار DEPOSIT و WITHDRAWAL است.
    • تراکنش‌هایی که از نوع DEPOSIT هستند، بیانگر واریزهایی هستند که مقصد آن‌ها، کیف پول فعلی است.
    • تراکنش‌هایی که از نوع WITHDRAWAL هستند، بیانگر برداشت‌هایی هستند که از کیف پول به حساب بانکی صاحب کیف پول منتقل می‌شوند.
  • وضعیت تراکنش (TransactionStatus): این کلاس یک enum است که به‌ترتیب شامل سه مقدار CANCELED، PENDING و ACCEPTED است.
  • تراکنش (Transaction)
    • این مدل به‌ترتیب شامل پراپرتی‌های زیر است:
      • long id: شناسه‌ی تراکنش
      • Wallet wallet: کیف پول مربوط به تراکنش
      • TransactionType type: نوع تراکنش
      • BigDecimal amount: مبلغ تراکنش
      • Date createdAt: زمان ایجاد تراکنش
      • TransactionStatus status: وضعیت تراکنش با مقدار اولیه‌ی PENDING
      • Date updatedAt: زمان تغییر وضعیت تراکنش
    • همه‌ی پراپرتی‌ها به‌جز پراپرتی updatedAt در کانستراکتور مقداردهی می‌شوند.
    • متد setStatus را طوری پیاده‌سازی کنید که با دریافت یک TransactionStatus، وضعیت تراکنش را به وضعیت واردشده تغییر داده و مقدار پراپرتی updatedAt را برابر با یک آبجکت جدید از نوع Date قرار دهد.

مخزن‌ها🔗

  • اینترفیس CrudRepository<T, ID>
    • این اینترفیس شامل دو پارامتر جنریک T (نوع مدل) و ID (نوع شناسه‌ی مدل) است.
    • این اینترفیس شامل تعریف متدهای زیر است:
      • boolean add(T t): این متد، مدل را به مخزن اضافه می‌کند؛ به شرط آن که مدل از قبل در مخزن وجود نداشته باشد. اگر مدل از قبل در مخزن موجود باشد، مقدار false و در غیر این‌صورت، مقدار true را برمی‌گرداند.
      • List<T> getAll(): این متد، لیست همه‌ی مدل‌های ذخیره‌شده را به‌ترتیب درج برمی‌گرداند.
      • T get(ID id): این متد، مدلی که شناسه‌ی آن برابر با id است را برمی‌گرداند. اگر چنین مدلی یافت نشود، مقدار null را برمی‌گرداند.
      • List<T> get(Predicate<T> predicate): این متد، لیست مدل‌هایی که شرایط داده‌شده در predicate را دارند به‌ترتیب درج برمی‌گرداند.
  • اینترفیس TransactionRepository
    • این اینترفیس از اینترفیس CrudRepository ارث‌بری می‌کند و صرفاً نوع تراکنش‌ها (که Transaction است) و نوع شناسه‌ی آن‌ها (که Long است) را مشخص می‌کند.
  • کلاس TransactionRepositoryImpl
    • این کلاس، اینترفیس TransactionRepository را پیاده‌سازی می‌کند و تراکنش‌های مربوط به همه‌ی کیف پول‌ها در آن ذخیره می‌شود.
    • متدهای این کلاس را مطابق توضیحات اینترفیس CrudRepository پیاده‌سازی کنید.
    • در متد add اگر مبلغ تراکنش کوچک‌تر یا مساوی صفر باشد، یک IllegalArgumentException باید پرتاب شود.

سرویس‌ها🔗

  • سرویس WalletService
    • از این کلاس برای مدیریت کیف پول‌ها استفاده می‌شود.
    • متد addTransaction را طوری پیاده‌سازی کنید که با دریافت یک تراکنش، با فراخوانی متد add از transactionRepository، آن را به لیست تراکنش‌ها اضافه کند. این متد در صورتی که تراکنش از قبل موجود باشد، باید مقدار false و در غیر این‌صورت، باید مقدار true را برگرداند.
    • متد getTransactions(Wallet wallet) را طوری پیاده‌سازی کنید که لیست همه‌ی تراکنش‌هایی که مربوط به کیف پول ورودی هستند را به‌ترتیب درج برگرداند.
    • متد getTransactions(Wallet wallet, Predicate<Transaction> predicate) را طوری پیاده‌سازی کنید که لیست همه‌ی تراکنش‌هایی که مربوط به کیف پول ورودی هستند و شرایط داده‌شده در predicate را دارند به‌ترتیب درج برگرداند.
    • متد getBalance را طوری پیاده‌سازی کنید که با دریافت یک کیف پول، موجودی حساب کیف پول را در قالب یک BigDecimal برگرداند. موجودی حساب برابر با مجموع مبلغ DEPOSITهای ACCEPTED منهای مجموع مبلغ WITHDRAWALهای ACCEPTED است.
    • متد setTransactionStatus را طوری پیاده‌سازی کنید که با دریافت یک تراکنش و وضعیت جدید، در صورتی که وضعیت تراکنش PENDING نبود یا وضعیت جدید برابر با PENDING بود، مقدار false را برگرداند. در غیر این‌صورت، اگر تراکنش از نوع WITHDRAWAL بود و موجودی کیف پول به اندازه‌ی مبلغ تراکنش نبود، یک IllegalArgumentException پرتاب شود. در غیر این‌صورت، وضعیت تراکنش به وضعیت جدید تغییر کند، مقدار پراپرتی updatedAt تراکنش به‌روز شود و مقدار true برگردانده شود.
  • سرویس AdminWalletService
    • این کلاس از کلاس WalletService ارث‌بری می‌کند.
    • متد getTransactions(Predicate<Transaction> predicate) را طوری پیاده‌سازی کنید که لیست همه‌ی تراکنش‌های مربوط به همه‌ی کیف پول‌ها که شرایط داده‌شده در predicate را دارند به‌ترتیب درج برگرداند.
    • متد getAllTransactions را طوری پیاده‌سازی کنید که لیست همه‌ی تراکنش‌های مربوط به همه‌ی کیف پول‌ها (همه‌ی تراکنش‌های موجود در مخزن) را به‌ترتیب درج برگرداند.

نکات🔗

  • لازم نیست که ذخیره‌سازی مقدار مدل‌ها persistent باشد (تنها یک بار اجرای برنامه را در نظر بگیرید).
  • هر نمونه از مخزن باید داده‌ها را به‌صورت جداگانه در خودش ذخیره کند.
  • در صورت نیاز، می‌توانید پراپرتی‌ها و متدهای جدیدی به کلاس‌ها (به‌جز کلاس Application) اضافه کنید.

مثال🔗

با اجرای متد main موجود در کلاس Application، خروجی زیر مورد انتظار است:

true
1000
[[Id: 1, Wallet Id: x-y-z, Type: DEPOSIT, Amount: 1000, Status: ACCEPTED]]
[[Id: 1, Wallet Id: x-y-z, Type: DEPOSIT, Amount: 1000, Status: ACCEPTED]]
Plain text

آن‌چه باید آپلود کنید🔗

پس از پیاده‌سازی موارد خواسته‌شده، یک فایل زیر آپلود کنید که وقتی آن را باز می‌کنیم، با ساختار زیر مواجه شویم (از سایر فایل‌ها صرف‌نظر می‌شود):

.
└── ir
    └── digipay
        └── digiwallet
            ├── model
            │   └── Transaction.java
            ├── repository
            │   └── TransactionRepositoryImpl.java
            ├── service
            │   ├── AdminWalletService.java
            └── └── WalletService.java
Plain text

تأیید هم‌روند


چند ماهی است که احمد یک وب‌سرویس پرداخت با نام بپرداز پیاده‌سازی کرده است. این وب‌سرویس اخیراً شاهد ترافیک سنگین درخواست‌ها بوده است. احمد برای رفع این مشکل، تصمیم گرفت تا از چند سرور مختلف برای پردازش درخواست‌ها استفاده کند. این سرورها با یکدیگر sync هستند؛ اما هم‌اکنون برخی از آن‌ها هم‌چنان به دلیل ترافیک بالای درخواست‌ها کند شده‌اند. از آن‌جایی که احمد هنوز راه‌حل درستی برای این مسئله پیدا نکرده، می‌خواهد یک تغییر موقتی روی SDK ای که در اختیار توسعه‌دهندگان قرار داده است اعمال کند.

احمد می‌خواهد SDK جاوای وب‌سرویسش را طوری پیاده‌سازی کند که درخواست تأیید یک تراکنش به‌صورت هم‌زمان به همه‌ی سرورهای موجود ارسال شود و به محض اولین پاسخی که از یکی از سرورها دریافت می‌شود، این پاسخ برگردانده شود. هم‌چنین، او می‌خواهد قابلیت ست کردن timeout وجود داشته باشد تا اگر پس از nn واحد زمانی هیچ پاسخی دریافت نشد، برنامه یک Exception پرتاب کند.

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

پروژه‌ی اولیه را از این لینک دانلود کنید.

کلاس TransactionVerifier🔗

این کلاس در کانستراکتور خود لیستی از URLهای مربوط به درخواست تأیید تراکنش را دریافت می‌کند.

  • بدنه‌ی کانستراکتور را به‌گونه‌ای تغییر دهید که اگر لیست URLها خالی بود، یک IllegalArgumentException پرتاب شود.
  • متد setTimeout را طوری پیاده‌سازی کنید که با دریافت یک واحد زمانی از نوع Duration، حداکثر زمان انتظار برای دریافت پاسخ را مشخص کند. هم‌چنین، مقدار پیش‌فرض timeout را برابر با ۳ ثانیه قرار دهید.
  • متد verify را طوری پیاده‌سازی کنید که با دریافت شناسه‌ی یک تراکنش (که از نوع String است)، درخواست تأیید تراکنش را به‌صورت هم‌روند به همه‌ی آدرس‌ها ارسال کند و به محض دریافت اولین پاسخ، آن را در قالب یک رشته برگرداند. این متد باید حداکثر به اندازه‌ی timeout ست شده منتظر پاسخ بماند. اگر timeout رخ دهد، این متد باید یک TimeoutException پرتاب کند. درخواست‌ها باید از نوع POST باشند و مقدار پارامتر transaction_id باید برابر با شناسه‌ی تراکنش قرار داده شود. بدنه‌ی درخواست باید از نوع JSON باشد.
  • متد getFastestServer را طوری پیاده‌سازی کنید که URL سروری که تاکنون بیش‌ترین پاسخ‌ها از آن دریافت شده است را برگرداند. اگر تعداد دفعات دریافت زودترین پاسخ از چند سرور یکسان بود، URL یکی از آن‌ها را به دلخواه برگردانید.

مثال🔗

با اجرای متد main، یکی از سه خروجی زیر مورد انتظار است:

{
    "sever_id": 1,
    "status": true
}
JSON
{
    "sever_id": 2,
    "status": true
}
JSON
{
    "sever_id": 3,
    "status": true
}
JSON

توجه: برنامه‌ی شما نباید resource leak داشته باشد.

آن‌چه باید آپلود کنید🔗

پس از پیاده‌سازی کلاس TransactionVerifier، فایل TransactionVerifier.java را آپلود کنید.

فروش انبوه


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

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

پروژه‌ی اولیه را از این لینک دانلود کنید.

  • این پروژه از Maven استفاده می‌کند و وابستگی‌ها در POM تعریف شده‌اند. امکان تغییر این وابستگی‌ها وجود ندارد.
  • از Liquibase برای مدیریت schema دیتابیس استفاده شده است.
  • برای اجرای تست‌ها، از دیتابیس H2 استفاده می‌شود.
  • در این پروژه، وابستگی Project Lombok تعریف شده و قابل استفاده است.
  • بسته‌ی ir.digipay.bulkshop شامل موجودیت‌های JPA برنامه است که مطابق با schema دیتابیس طراحی شده‌اند. شناسه (id) موجودیت‌ها به‌صورت خودکار توسط Hibernate تولید می‌شود.
    • کلاس CustomerEntity: از این کلاس برای نگه‌داری اطلاعات هر مشتری استفاده می‌شود.
    • کلاس ProductEntity: از این کلاس برای نگه‌داری اطلاعات هر محصول استفاده می‌شود.
    • کلاس OrderEntity: از این کلاس برای نگه‌داری اطلاعات هر سفارش استفاده می‌شود.
  • بسته‌ی ir.digipay.bulkshop.api شامل کلاس‌هایی برای مدیریت ورودی‌ها و خروجی‌های API است.
  • بسته‌ی ir.digipay.bulkshop.rest شامل REST controller های برنامه است. کنترلر مربوط به آدرس / برای تست برنامه در کلاس IndexRestEnpoint پیاده‌سازی شده است. سایر کنترلرها را در این بسته پیاده‌سازی کنید.
  • از آن‌جا که این برنامه اولین نسخه‌ی سامانه است، هر سفارش می‌تواند شامل یک نوع محصول باشد، اما تعداد آن را می‌توان در سفارش تعیین کرد.

سرویس‌ها🔗

تعدادی وب‌سرویس REST مطابق نیازمندی‌های زیر باید پیاده‌سازی شود:

آدرس عنوان
GET /api/products دریافت اطلاعات محصولات
POST /api/products ایجاد محصول
GET /api/products/{id} دریافت اطلاعات یک محصول
PUT /api/products ویرایش اطلاعات یک محصول
GET /api/customers دریافت اطلاعات مشتریان
POST /api/customers ایجاد مشتری
GET /api/customers/{id} دریافت اطلاعات یک مشتری
PUT /api/customers ویرایش اطلاعات یک مشتری
GET /api/orders دریافت اطلاعات سفارشات
POST /api/orders ایجاد سفارش
GET /api/orders/{id} دریافت اطلاعات یک سفارش

دریافت اطلاعات محصولات🔗

اطلاعات همه‌ی محصولات در قالب یک آرایه برگردانده می‌شود:

URL: "GET /api/products"

http-code: 200
content-type: "application/json"
response: {
  "products": [ # Array of ProductModel or ProductEntity
    {
      "id": "some_uuid",
      "name": "x",
      "price": 50000,
      "availableCount": 100
    },
    {
      "id": "some_uuid",
      "name": "y",
      "price": 75000,
      "availableCount": 50
    }
  ]
}
YAML

ایجاد محصول🔗

یک محصول با اطلاعات اولیه‌ی داده‌شده ایجاد می‌شود و شناسه‌ی آن برگردانده می‌شود:

URL: "POST /api/products"

request: { # ProductCreateParam
  "name": "x",
  "price": 40000,
  "initialAvailableCount": 100
}
http-code: 201
content-type: "application/json"
response: { # ProductCreateResult
  "productId": "some_uuid"
}
YAML

دریافت اطلاعات یک محصول🔗

شناسه‌ی محصول به‌عنوان ورودی داده می‌شود و اطلاعات محصول برگردانده می‌شود:

URL: "GET /api/products/1234"

http-code: 200
content-type: "application/json"
response: { # ProductModel or ProductEntity
  "id": "some_uuid",
  "name": "z",
  "price": 40000,
  "availableCount": 150
}
YAML

اگر محصولی با شناسه‌ی واردشده موجود نباشد، پاسخ باید به‌صورت زیر باشد:

http-code: 404
content-type: "application/json"
response: { 
  "message": "Entity not found"
}
YAML

ویرایش اطلاعات یک محصول🔗

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

URL: "PUT /api/products"

request: { # ProductUpdateParam
  "id": "some_uuid",
  "name": "x2",
  "price": 51000,
  "availableCount": 200
}
http-code: 204
YAML

اگر محصولی با شناسه‌ی واردشده موجود نباشد، پاسخ باید به‌صورت زیر باشد:

http-code: 404
content-type: "application/json"
response: { 
  "message": "Entity not found"
}
YAML

دریافت اطلاعات مشتریان🔗

اطلاعات همه‌ی مشتریان در قالب یک آرایه برگردانده می‌شود:

URL: "GET /api/customers"

http-code: 200
content-type: "application/json"
response: {
  "customers": [ # Array of CustomerModel or CustomerEntity
    {
      "id": "some_uuid",
      "username": "x",
      "firstName": "x",
      "lastName": "x"
    },
    {
      "id": "some_uuid",
      "username": "y",
      "firstName": "y",
      "lastName": "y"
    }
  ]
}
YAML

ایجاد مشتری🔗

یک مشتری با اطلاعات اولیه‌ی داده‌شده ایجاد می‌شود و شناسه‌ی آن برگردانده می‌شود:

URL: "POST /api/customers"

request: { # CustomerCreateParam
  "username": "z",
  "firstName": "Z",
  "lastName": "z"
}
http-code: 201
content-type: "application/json"
response: { # CustomerCreateResult
  "customerId": "some_uuid"
}
YAML

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

http-code: 409
content-type: "application/json"
response: { 
  "message": "Username already taken"
}
YAML

دریافت اطلاعات یک مشتری🔗

شناسه‌ی مشتری به‌عنوان ورودی داده می‌شود و اطلاعات مشتری برگردانده می‌شود:

URL: "GET /api/customers/1"

http-code: 200
content-type: "application/json"
response: { # CustomerModel or CustomerEntity
  "id": "some_uuid",
  "username": "x",
  "firstName": "x",
  "lastName": "x"
}
YAML

اگر مشتری‌ای با شناسه‌ی واردشده موجود نباشد، پاسخ باید به‌صورت زیر باشد:

http-code: 404
content-type: "application/json"
response: { 
  "message": "Entity not found"
}
YAML

ویرایش اطلاعات یک مشتری🔗

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

URL: "PUT /api/customers"

request: { # CustomerUpdateParam
  "id": "some_uuid",
  "username": "x2",
  "firstName": "x2",
  "lastName": "x2"
}
http-code: 204
YAML

اگر مشتری‌ای با شناسه‌ی واردشده موجود نباشد، پاسخ باید به‌صورت زیر باشد:

http-code: 404
content-type: "application/json"
response: { 
  "message": "Entity not found"
}
YAML

دریافت اطلاعات سفارشات🔗

اطلاعات همه‌ی محصولات در قالب یک آرایه برگردانده می‌شود:

URL: "GET /api/orders"

http-code: 200
content-type: "application/json"
response: {
  "orders": [ # Array of OrderModel or OrderEntity
    {
      "id": "some_uuid",
      "customerId": "some_uuid",
      "productId": "some_uuid",
      "count": 4
    },
    {
      "id": "some_uuid",
      "customerId": "some_uuid",
      "productId": "some_uuid",
      "count": 3
    }
  ]
}
YAML

ایجاد سفارش🔗

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

URL: "POST /api/orders"

request: { # OrderCreateParam
  "customerId": "some_uuid",
  "productId": "some_uuid",
  "count": 6
}
http-code: 201
content-type: "application/json"
response: { # OrderCreateResult
  "orderId": "some_uuid"
}
YAML

اگر مشتری یا محصولی با شناسه‌ی واردشده موجود نباشد، پاسخ باید به‌صورت زیر باشد:

http-code: 404
content-type: "application/json"
response: { 
  "message": "Entity not found"
}
YAML

اگر مقدار فیلد count کوچک‌تر یا مساوی صفر باشد، پاسخ باید به‌صورت زیر باشد:

http-code: 400
content-type: "application/json"
response: { 
  "message": "Invalid count"
}
YAML

اگر مقدار count بزرگ‌تر از موجودی فعلی محصول باشد، پاسخ باید به‌صورت زیر باشد:

http-code: 400
content-type: "application/json"
response: { 
  "message": "Not enough available count"
}
YAML

دریافت اطلاعات یک سفارش🔗

شناسه‌ی سفارش به‌عنوان ورودی داده می‌شود و اطلاعات سفارش برگردانده می‌شود:

URL: "GET /api/orders/1234"

http-code: 200
content-type: "application/json"
response: { # OrderModel or OrderEntity
  "id": "some_uuid",
  "customerId": "some_uuid",
  "productId": "some_uuid",
  "count": 5
}
YAML

اگر سفارشی با شناسه‌ی واردشده موجود نباشد، پاسخ باید به‌صورت زیر باشد:

http-code: 404
content-type: "application/json"
response: { 
  "message": "Entity not found"
}
YAML

نکات🔗

  • ممکن است چند درخواست هم‌زمان برای خرید یک محصول به برنامه ارسال شود. این درخواست‌ها باید به‌درستی مدیریت شوند.
  • شما تنها مجاز به اعمال تغییرات در بسته‌ی ir.digipay.bulkshop هستید.

آن‌چه باید آپلود کنید🔗

پس از پیاده‌سازی موارد خواسته‌شده، پوشه‌ی src پروژه را زیپ کرده و ارسال کنید. توجه داشته باشید که فقط تغییرات اعمال‌شده در پوشه‌ی src/main/java/ir.digipay.bulkshop در نظر گرفته می‌شوند.