続行の主なアイデア:マップ上に利用可能な車を表示して、カーシェアリングサービスのアプリケーションサービスを開発する。コンテンツでは、車両、バイク、車両などのVehicles本質と比較できるすべてのもの。アプリケーションは多機能である必要があります。
pager -Aをページに追加します。httpContextAccessorに基づいてユーザーと協力します。UserStatusProviderステータスの保管施設への移行。 SweetAlert2サービスを使用してJSメッセージを追加します。ReadMeと協力します。Stripe支払いサービスのテストモードでの接続。注文の配置により、ページに日付と日付の選択の機能を追加します。JSコードの場所を変更しました(ファイルで破壊されました)。Brief Description追加しました。彼は車の評価に参加し始めました。.NET 7への移行。カタログページの検索エンジンで作業します。RepositoryProviderに置き換え、そのすべての機能を削減します。WebアプリケーションコントローラーにJWToken Authenticationが追加。JWTokenと連携し、クライアント側のエラーのページ表示をセットアップします。JSONファイル、 MongoDB Localのストレージへの移行のためにリファクタリング。MongoDB Atlasクラスターを設置します。UIで作業します。 Google Maps APIマーカーを赤から車に変更し、名前と画像を変更します。インターンシップの公式の開始
Webアプリケーションから完全なClean Architectureへの移行。Domain Layerを使用して最初のモデルをセットアップします。モデルはRich Domain Modelsスタイルで作成されます。 Anemic Domain Models 。ApplicationとInfrastructure Layersを操作し、サービスとの最初のやり取りを設定してDIを設定します。PublicAPIした。endpointsとその手動テストのセットアップ。Errors Handlingとその処理に関する作業の開始。Vehicleモデルの一部にErrors Handlingを追加します。endpointsでのテスト。Azure Key Vault機能を追加して、 Azureを使用して秘密データを取得します。自動車に関する情報を保存するためのオプションの1つとして、噛むフラグの実装。CustomerControllerとその手動テストに新しいendpointsを追加します。VehicleControllerとその手動テストに新しいendpointsを追加します。IHttpClientFactoryを追加して、 PublicAPIにレクエットを送るための顧客を作成します。重要な状況の場合に待機して再検討する可能性を備えた非メトナム送信メッセージのPolly構成。WebパーツとともにPublicApiによるバインディング、およびエンドポイントとプログラム間のシリアル化と脱脂をチェックします。JWTokenを保存します。UIページの作業。errors handlingを追加します。htmlページといくつかのendpointsの取り消し。Bootstrap 5+新しいバージョンに移行し、登録と承認のページのロジックを削除します。GoogleMaps Apiおよびエラー修正を使用します。Appsettings.jsonファイルの操作。設定とDuende Identity Serverとの最初のやり取り。Identity Serverのルールを設定し、不要なファイルからプロジェクトをクリーニングしました。Duende Identity ServerへのバインディングWeb Application (クライアントパーツ)。Duende Identity Serverを使用して、カスタムメイドのJWT-AuthorizationとDashboardページ(ユーザーパーソナルアカウント)の作成に戻ります。MongoDB Entitiesと協力するためのDuende Identity Serverを構築する試み。Duende Identity Server削除。 AzureAD許可の方法の1つとして設定します。 MSSQL Serverに新しいエンティティを追加します。Identity Serverの設定に関連するファイルからプロジェクトのクリーニング。JwtBearerを通じて承認を求めるチューニング。 AzureADの設定。車の画像を保存するためのメカニズムの1つとして、接続Azure Blob Storage 。Pipelineが設定されました。 ActionNotes Repositoryアプリケーションのサービスの1つとして追加します。Dashboardページに顧客に関するデータの表示に関連する新しい機会が追加されます。新しい列が追加されたデータベースの構造を更新しました。 Pipeline 、クライアントのアカウントに関する情報を送信するデータを受信するように構成されています。Dashboardページで作業します。Dashboardページで車両に関連するアクションの設定。 ajax関数が追加されて、更新せずにページをダウンロードします。基準によって検索機能を追加しました。pipeline供給カタログ内の車のデータを表示します。GoogleMaps Apiを使用するための新しいページを追加します。Stripe Payment Serviceとの統合の追加。VehicleInformationページを操作する際のソフトウェア方法の作業。Azure VMと協力。 azurevmでSeqおよびホスティング例外サービスを設定します。 MSSQLデータベースへの海軍申請のアクセスを設定します。Main branchとMergeたGitHub Actionsと自動Publishの作業。HttpからHttpsへのサイトの転送と新しい機能の追加に取り組みます。RentalおよびPaymentモデルとAzure VM Moodの追加。Stripe Payment Serviceと対話するための別のサービスに取り組みます。Stripeに関連するエラーの排除に取り組みます。 Stripe Checkout Sessionsの作成に取り組みます。RequestsとResponsesを設定します。Runtime処理と注文のステータスを変更するときにフォームの取得。DateTimeとデータベースでの要求、アプリケーションの機能に関する取り組みの誤りの修正。Routing-омとページ表示のセットアップの作業。.tagetsファイルを追加して、同じパッケージのバージョンの問題を異なるプロジェクトで解決します。Endpointsで作業して、カーデータを編集します。pipelineの最終的な構成。server responseアナライザーに取り組み、これらのresponsesの普遍的なハンドラーを設定します。DateTime.Now (現地時間)からオブジェクトDateTime.UtcNow (UTC Time)へのサイト全体の翻訳。REST 3月16日 - サーバーパーツのRouting設定。pipelineの作業。このプロジェクトは、 PublicAPIと同じレベルで動作する完全なWebアプリケーションであり、 Clean Architectureスタイルで書かれています。これにより、有効なレンタルカードと運転免許証を持っている人は、他のユーザーの車を他のユーザーの車に手に入れることができます。したがって、アプリケーションの開発者がユーザーが行ったトランザクションの割合を受け取ることと、ユーザー自身が車をレンタルまたはリースしていることを直接受け取ることができます。
Stripeとの統合)SweetAlert2 )Google Maps API )Stripe )ErrorOr NuGet Package )JWT Bearer NuGet Package )Azure Key Vault )Azure Blob Storage )Azure AD )Seq Service )Polly )Lets Encrypt Service )PVS Studio )MSSQLおよびMongoDB )GitHub ActionsとAction Runners )Azure VM )そして他の...
プロジェクト全体は、 bootstrap 5+を使用して視覚コンポーネントを飾るだけでなく、 Razor Pagesの機能を使用して、 backendコンポーネントを作成するためにC# .NET Core使用して、ゼロから作成されました。相互作用のモデルとして、私はMVCに向けて選択しました。出口では、 Client-Server MVC Wep Appを扱っています。

許可されていないユーザーがアプリケーションを起動するとすぐに、彼はすぐにサービスに関する情報を含むメイン画面を確認します。このページには、サービスのすべての機能を備えた新しいユーザーに慣れるために必要なすべての情報が含まれています。上部には、 navbar要素が表示されます。これは、どのページでも常にページでは、付録でユーザーナビゲーションを実行するように設計されたビジョンフィールドから消えません。 Navbar次の機会を提供します。

また、ページには、Googleのマップがあります。これは、カタログからレンタカーされていないすべての利用可能な場所の場所を示しています(マップにマーカーが表示されます。これに応じて、車両の現在の場所を追跡できます。マーカーに委託すると、名前のある車両の画像が表示されます)。制限として、私はミンスク市を選びました。つまり、マップは都市の全地域をカバーするような方法で位置しています。たとえば、車がブレストの路上のどこかにある場合、マップ上に表示されません(または、カードのスケールを変更する必要があります)。車を配置するための利用可能な場所として、私は自分自身をベラルーシに限定することにしました。つまり、認定されたユーザーによって配置された車はベラルーシ共和国にあるべきです。ただし、ユーザーが別の都市や国で車の注文を作成することを妨げるものはありません。
カード自体に関しては、有名な緯度と経度に応じて場所を見つけるための制限なしに機能する特別なキーを使用してアプリケーションに接続されていました。

ページに関係なく、最下部には、アプリケーションの開発者に関する情報と、対応するソーシャルへのリンクがあります。 SAMソリューションネットワークとリソース。

カタログのページでは、ユーザーには、車に関する手頃な価格のすべての簡単な情報を表示する機会が与えられ、カタログに記載されている車の基準を検索する機会が与えられます。ページには機会があります:

車に関する情報については、カタログが提示されます。

また、このページには、車両のポイント検索の実装に必要なフォームを引き起こす機会があります。ここでは、多くの異なるフィルターがユーザーに提供されており、カタログで彼に興味のある車を見つけることができます。
したがって、カタログでは、提示された車両の品揃えを検討し、好みと色にコピーを選択できます。
ユーザーがLog In押すとすぐに、彼はすぐに承認ページにリダイレクトします。

許可されていないユーザーである承認ページでは、承認を成功させるためにメール(またはログイン)とパスワードを入力する必要があります。フィールドに記入する際のエラーの場合、記入時にエラーメッセージが表示されます。

すべてのフィールドが正しく入力されているが、承認が通過していない場合、ユーザーは失敗した許可に関するメッセージを提示します。

承認が成功すると、既に認可されたユーザーがダッシュボードページ(個人アカウント)にリダイレクトされ、その上に成功した許可に関するメッセージが表示されます。

ユーザーが独自のアカウントを持っていない場合、ユーザーは自分のアカウントを作成する必要があります。右のNavbar要素のSign Upボタンを押すと実行されるページへの移行を実装する必要があります。


新しいユーザーの登録があるページでは、プログラムがデータベースに入力し、登録が成功するように、一連のデータを入力する必要があります。ページ全体が検証で満たされており、何かが合格しない場合、ユーザーはエラーが発生したフィールド(承認の恥ずかしさと同じ原則)を通知されません。登録が成功した後、ユーザーは登録ページにリダイレクトされます。このページでは、登録の成功に関するメッセージが表示されます。
ユーザーが新しく作成されたアカウントに正常に入力するとすぐに、カタログ内の車に関するより詳細な情報を表示するだけでなく、自分の車を追加するだけでなく、他のユーザーによるアクションとアクションに関する統計を追跡する機会も得られます。


このページでは、ユーザーは自分の車に関する関連情報を提供するだけでなく、車がレンタルされる関税を設定する必要があります。ページには検証もあります(承認と登録ページと同様)。ユーザーが自分の車を正常に共有するとすぐに、それはすぐに彼のアカウントに表示されますが、その公開のために、管理者はアプリケーションを承認する必要があります。その後、ユーザーは自分のアカウントを通じて車を公開し、情報を編集してこの車と対話することができます。 (ユーザーが車を追加したため、カタログに同じユーザーに表示することは完全に論理的で正しいことではないことが論理的です。しかし、彼らはまだカタログに表示されますが、この車に関する情報をページに移動することで、所有者はそれを借りることができませんが、彼は他のユーザーの説明と表現に精通することができます)。
承認されたユーザーへのダッシュボードページで、アカウントの統計を乾燥させることを請うことが提案されています。このページでは、ユーザーは次のような情報を次のように表示できます。
ダッシュボードページから、ユーザーは、車に関する情報を編集するか、アカウント情報の編集ページでページにアクセスする機会があります。

ヘッドページを使用すると、ユーザーはアカウントに関連付けられた一部のフィールド(名前、姓、ニックネーム、メールなど)を変更できます。
ヘッドメニューには左側にいくつかのボタンがあり、そのうち2を押した後、ミニワインドがあり、アカウントの情報を変更するのにも役立ちます。

ヘッドページの対応するボタンをクリックすると、ユーザーは自分のプロフィールを表すアバターのいずれかを選択するように招待されます。ユーザーがアバターの1つを選択するとすぐに、その後、 Apply Save changesボタンが更新され、ユーザーはアカウントの別の画像を観察できます。

次のボタンが押されると、ユーザーはアカウントから新しいパスワードを入力する機会があり、その後、アカウントからのパスワードが完全に更新され、アカウントを再入力すると古いパスワードが無効になります。

ユーザーがアカウントに新しい車を追加し、管理者によって正常に確認されると、ユーザーは自分の車を公開することができます(彼は他のユーザーに賃貸料を味わう)、またはそれを隠すことができます。車が隠されている場合、対応するメニューをクリックすると、ユーザーは対応するModifyボタンをクリックしてから、車の情報を編集してページに移動できます。
このページでは、彼は車に関する全体的な情報を変更することができます(ただし、彼がそのような機会があれば、管理者によって車を確認した後、他のユーザーがカタログに不正確で普遍的な情報を見たことができるという目的のために、彼は車と彼のカテゴリーを変更することはできません)。
TODO:下にあるすべてを変更します。

認定ユーザーがカタログから車両のInformationボタンを押すとすぐに、選択した車とコピーに関するより詳細な情報で対応するページを開きます。このページから、すぐに、ユーザーの個人アカウントに記録される注文を作成することが可能になります。
許可後にユーザーの個人アカウントに移行するためのボタンを追加しました。これにより、ユーザーは注文と車を追跡できます(これまでのところ、ボタンのみPublishおよびHideボタンのみが車と対話するためにアクティブです)。


このページでは、ユーザーは情報を表示および変更するだけでなく、車と注文を制御することもできます。ユーザーデータの後、次のカウンターを見ることができます。
また、このページでは、次のような情報を表示できます。
車のテーブルで作業するときは、3つの色を観察できます。
車の状態と色に応じて、新しい/古い機能はユーザーに開いている/ブロックされています
上記のように、認可されたユーザーシステムの場合、彼の個人アカウントを入力し、彼の注文に関連するすべての情報、およびこのユーザーが当社のサービスの他のユーザーに提供した車を追跡することが可能になります。しかし、いくつかの情報が入力されなかった場合、ユーザーのデータが変更された場合、または車を公開したユーザーが、他の人の背景に何らかの形でвыделтьсяことに決めた場合はどうでしょうか?これらの問題を解決するために、私は現在のユーザーに関する情報を編集し、彼の車に関するページを作成しました。
個人アカウントから、自分に関する情報を編集してページに移動します。ユーザーは、対応するEdit Profileボタンをクリックしてできます

押すと、ユーザーはページに表示される情報を変更できるページを開きます

特に:そのプロファイルのアバター(提案された7つの画像から選択する(1つのデフォルト、各新しいユーザーに割り当てられ、6つは選択できる6つ))

パスワードを変更することもできます。前のパスワードが必要ないように新しいパスワードを確立しました(実際には、新しいパスワードをインストールする前に実際のパスワードをリクエストする必要があります)

単純なものから、ユーザーはこのページのフィールドを変更できます(たとえば、プロファイル、彼の電話番号、電子メールなどの説明など)。すべてのフィールドユーザーが変更されたら、対応するSave Changesボタンをクリックする必要があります(新しいパスワードをインストールすると、 Saveボタンがページに押されたときに新しいパスワードが自動的にインストールされます)。フィールドに入力するときに何らかのエラーが発生した場合、ユーザーはCancel Chnagesボタンをクリックします。これにより、ページを元のフォームに戻す(古いデータにトイビング)、またはGet Backボタンを押します。
実際、車に関しては、ユーザーはこれまたはページの以前の情報を変更することもできます。

ただし、変更に使用できるフィールドの数は、ユーザーの数倍です。なぜそうですか?事実は、発展時にアイデアが私に起こったということです。すべての車は注文数で監視されます。しかし、ユーザーが車を完全に変更できる場合、たとえば、自分のイメージと名前を変更できるとしたらどうでしょうか?この車の評価は同じままですが、詳細な説明は完全に変更されていました。私にとっては、そのようなアプローチは、他のユーザーを決定する上で重要な役割を果たす可能性があります。たとえば、1年前に自分の車を置いたユーザーは、古い車の説明をより新しい車の説明に変更するユーザーに明らかに負けます。したがって、私は情報を編集から隠す必要があり、最も必要なフィールドのみが利用可能であると結論付けました:関税、説明、および場所。
認定ユーザーのDuboは、カタログ内の他のユーザーの車に関する詳細情報を表示できます。各車のページから、ユーザーはこの車を使用するための注文の配置でページに移動できます。

このページでは、彼は車を使用できる期間を選択するよう招待されています。

時間間隔の選択は、私がインストールしたdaterangepicker要素を使用して実行されます:開始時間 - 次の時間に向かって丸くなります。終了時間(デフォルト)は開始時間 + 1時間です。したがって、車を使用するための最小時間は1時間です。私が設定した迷路の時間は、最初から7日です。支払い額の計算は、式に従って発生します。日数に関税/日 +時間数 *関税/時間を掛けます。ユーザーが必要なすべての準備を行い、注文を確認するとすぐに - 支払いページにリダイレクトされます。

支払いページでは、ユーザーに必要なすべての情報が、再度注文を再描画するために与えられます。支払いが行われるとすぐに、ユーザーは個人アカウントで車を見つけることができます。車を所有しているユーザーは、車がレンタルされていることを確認し、車をレンタルしたユーザーは、この車のリースの終わりの残りの時間と時間に関するすべての情報と同様にすべての情報を見ることができます。次のように見えます:

ユーザーがスケジュールよりも早く注文を完了することを決定した場合(注文は期限切れの注文の責任者ではなく、注文を行ったユーザーで終了します)、彼は次の時間に使用した車の評価を設定する機会があります。

繰り返しますが、ユーザーには選択肢があります。車の評価を入れてから、対応するSubmit and Finishボタンを押して評価を使用して注文を完成させるか、フィニッシュをクリックしてFinish and not submitでステップをスキップし、評価を送信せずに注文を完了します。
評価自体は、車に関する情報とともにページに表示されます。ユーザーが設定した評価に応じて、一般的な統計がページに表示されます。星が0の車を上に見ることができ、1つのユーザーからの定格評価のある車のあるページを以下に示します。

このセクションでは、私は説明しようとしますが、プロジェクトが内部からどのように配置されるか、「ブラックボックス」内で起こっていることを説明します。これは、C#プログラミング言語とプログラミングの側面について少なくとも少しのアイデアを持っている人のためのプロジェクトをよりよく理解するのに役立ちます。
もちろん、データを操作するには、スターターのために、あなたはそれらを保存する方法を決定する必要がありますか? Of course, super large projects are used for storage such a database as Oracle, PostgreSQL, MySQL, MSSQL and others. However, the problem of this approach is that access to applications tied to databases can only be obtained if the connection to the same database can be obtained on the user's device (for such a function you have to pay large amounts of money to gigants). Since I do not have large amounts of money, in order to start the project to any user and not experience problems with its testing and use, I put forward the idea of using serialization and decering in the contexts of relative paths. Thus, the problems with obtaining access from users who downloaded the application from the repository should not arise.
Каким же образом происходит получение данных из JSON-файлов и как вообще устроено получение данных? (Для всех локальных хранилищ)
Для того, чтобы не привязываться к какому-то определённому типу хранилищ, мной был применён подход Dependency Injection, а именно внедрение Singleton зависимостей между хранилищами и локальным репозиторием программы. То есть: в моей программе есть интерфейс:
public interface IVehiclesRepositoryЭтот интерфейс будет являться связующим звеном для получения данных. В данном интерфейсе есть набор методов, которые должны быть реализованы для того или иного сервиса, чтоб им можно было пользоваться независимо от реализации методов. Главное, чтоб эти методы были реализованы в том классе, который решит реализовать этот интерфейс. Для реализации локального интерфейса, так как я исользую локальное хранилище данных в файлах, а не в БД, я решил использовать Singleton подход, что будет означать, что объект сервиса будет создаваться только при первом обрпщении к нему, после чего все последующие запросы будут проходить через тот самый сервис. Ниже, мы явно указываем, что если кто-то захочет получить объект этого сервиса через интерфейс, мы дадим ему конкретную реализацию (В данном случае реализацию локального репозитория):
builder . Services . AddSingleton < IVehiclesRepository , VehiclesLocalRepository > ( ) ; // Где требуется IVehiclesRepository - дай реализацию VehiclesLocalRepositoryСами же локальные репозитории реализованы таким образом, чтоб уменьшить количество загрузок из файлов в само приложение. Как только происходит первое обращение к сервису - производится работа метода SetUpLocalRepository. Этот метод запишет в путой объект List<> модели, считанные из JSON - файла, после чего все манипуляции будут проходить непосредственно через сам этот List<>, а если данные будут меняться - будет вызываться асинхронный метод SaveChanges(), который призван асинхронно записать изменения в файл (Повторное считывание файла не происходит, так как мы работаем с объектом List<>, который мы также изменили перед тем, как запрашивать обновление JSON-файла). Таким образом, применённый мной подход не только позволит пользователю получать доступ в кратчайшие сроки, но и позволит избежать излишних нагрузок системы для загрузки данных из файлов каждый раз при обращении к сервису.
In design, I identified the following problem - should the user who added the car to the catalog be able to interact with the same car from the catalog?もちろん違います。 This approach will allow the user who added the car to the directory to rent his own car (what's the point ???). To avoid this problem, I chose the following approach:
Imagine that at the moment, there are no users or added cars. Here we are launching our application. On the main page we see a map with 0 markers, and in the catalog there are also 0 cars. We create a new account, enter it, share our car.しかし! The car does not appear in the catalog.何が問題ですか? The fact is that before displaying the car in the catalog, the user who added it should clearly publish a car from his personal account by clicking the Publish button opposite the selected car. As soon as he has been published, nothing will change for this user in the catalog, he will also see 0 cars.しかし! If we leave the account or create a new one, the catalog will be seen in the catalog that the same car that he shared and which was published by the previous user. Thus, the user who added the car and placed it in the catalog cannot see his own cars (the user can see all his added cars in his personal account).しかし! After the user shares his car and places it in a catalog from his personal account, although he does not see this car in the catalog, he can go to the main page and pay attention to the fact that his car appeared on the marker’s form (however, he still does not have in the catalog). The fact is that the system shows any user all cars on the map in the form of a marker, which were published in your personal account, regardless of which user is now in the system. However, in the catalog, the system shows the same cars that are shown on the map on the main page in the form of markers, but the condition is also checked that the ID of the owner of the car is not equal to the ID of the current user entering the account. For an unauthorized user, the ID is not checked. He is shown the same cars in the catalog as on the map on the main page.
Таким образом, подводя итог:
Publish (И пропадёт, если он решит убрать его из каталога путём нажатия кнопки Hide ) При добавлении автомобиля, на странице использованы такие технологии, как локальное хранилище данных (Local Storage) для хранения координат местоположения автомобиля, а также специальные скрипты и элемент C# IFormFile для получения файла изображения со сраницы.
Local Storage
Предположим, что мы - очень невнимательные пользователи, которые всё время допускают ошибки на страницах. Для того, чтобы избежать повторного ввода координат каждый раз при обновлении страницы, пной было принято решение хранить координаты GoogleMaps в локальном хранилище и чистить эти данные в случае покидания пользователем страницы добавления своего автомобиля. Так как данные, применяемые при работе с GoogleMaps являются специфическими (представление типа данных float отличаются знаком разделителя) чтоб избежать большого количества манипуляции с данными, используется локальное хранилище, которое призвано сократить число операция приведения данных из одного представления в другое.
IFormFile и скрипты
При работе с изображеним, мы не можем получать доступ к файловой системе пользователя со страницы Razor, так как это просто недопустимо в рамках работы системы безопасности, поэтому приходится использовать определённые подходы, например, как работа с IFormFile. Объекты этого типа хранят всю необходимую информацию о выбранном изображении, которое выберет пользователь, при этом не представляет никакой угрозы для файловой системы компьютера в целом. Однако использование такого подхода имеет недотаток - пользователю необходимо каждый раз выбирать изображение снова и снова, если пользователем повторно допускаются ошибки на странице добавления автомобиля.
Ниже я постарался описать интересные технические моменты, которые я предпринимал в течение проектирования и разработки проекта.
При работе с получением автомобилей из репозитория у меня было 2 идеи, как решить данную задачу: Либо при каждом обращении к контроллеру формировать новый объект с информацией о машинах и передавать его во View , либо же принимать этот объект из View , если он уже был передан однажды, при этом не делая никаких дополнительных запросов в репозиторий, и модифицировать согласно предпочтениям пользователя по количеству отображения автомобилей на странице и тд. Сначала я принял решение пойти через получение модели из View , однако столкнулся с такой проблемой, как Model Binding , которая просто так не даёт получить List переданных в качестве модели автомобилей: Либо нужно использовать Ajax , при этом заранее сериализовать модель в JSON и после чего десериализовать полученную JSON -строку в Controller-е , либо никак) Поэтому я выбрал первый путь (через создание объекта), так как в этом случае придётся манипулировать в основном со ссылками на данные, нежели чем с самими данными. (ps Также, работа через первый подход потребовала бы накладных расходов на проверку, а не добавилась ли в репозиторий новая машина, но уже другим пользователем, и если добавилась, также необходимо было бы добавить её в модельку, пришедшую из View )
Изначально, мной была заложена идея, что пользователь может как оформить заказ на определённое время, внеся предоплату, так и просросить его, за что потребуется внести дополнительные деньги за просроченное время. Однако, при дальнейшем развитии идеи, мной были выявлены следующие проблемы, касательно как программной, так и правовой идеи такого подхода:
Поэтому, мной был выбран следующий план действий: Подразумевается, что заказ начинается, как только пользователь оформляет заказ на пользование авто и оплачивает его, а заканчивается этот же заказ ровно тогда, когда время пользования станет равно оплаченному времени. После чего, автомобиль сразу становится доступным для других пользователей в каталоге, а нынешний заказ пропадает с личного кабинета пользователя, оплатившего время на его использование. Если другой пользователь оформит заказ на тот же автомобиль и при прибытии на место обнаружит, что автомобиль отсутствует на том месте, на котором он расположен на карте, он имеет право подать в суд на человека, который просрочил своё время (собственно как и заказчик). Таким образом, каждый пользователь, который оформляет заказ, берёт на себя ответственность закончить его во время.