initallCodeAfterError
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,4 +1,3 @@
 | 
			
		||||
# ---> VisualStudio
 | 
			
		||||
## Ignore Visual Studio temporary files, build results, and
 | 
			
		||||
## files generated by popular Visual Studio add-ons.
 | 
			
		||||
##
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@
 | 
			
		||||
            "tsConfig": "tsconfig.app.json",
 | 
			
		||||
            "inlineStyleLanguage": "scss",
 | 
			
		||||
            "allowedCommonJsDependencies": ["chart.js", "js-sha256"],
 | 
			
		||||
            "assets": ["src/favicon.ico", "src/assets"],
 | 
			
		||||
            "assets": ["src/favicon.ico", "src/assets", "src/manifest.webmanifest"],
 | 
			
		||||
            "styles": [
 | 
			
		||||
              {
 | 
			
		||||
                "input": "node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.css",
 | 
			
		||||
@ -112,7 +112,9 @@
 | 
			
		||||
              },
 | 
			
		||||
              "src/styles.scss"
 | 
			
		||||
            ],
 | 
			
		||||
            "scripts": []
 | 
			
		||||
            "scripts": [],
 | 
			
		||||
            "serviceWorker": true,
 | 
			
		||||
            "ngswConfigPath": "ngsw-config.json"
 | 
			
		||||
          },
 | 
			
		||||
          "configurations": {
 | 
			
		||||
            "production": {
 | 
			
		||||
@ -173,7 +175,7 @@
 | 
			
		||||
            "tsConfig": "tsconfig.spec.json",
 | 
			
		||||
            "karmaConfig": "karma.conf.js",
 | 
			
		||||
            "inlineStyleLanguage": "scss",
 | 
			
		||||
            "assets": ["src/favicon.ico", "src/assets"],
 | 
			
		||||
            "assets": ["src/favicon.ico", "src/assets", "src/manifest.webmanifest"],
 | 
			
		||||
            "styles": ["src/styles.scss"],
 | 
			
		||||
            "scripts": []
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										30
									
								
								angular/ngsw-config.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,30 @@
 | 
			
		||||
{
 | 
			
		||||
  "$schema": "./node_modules/@angular/service-worker/config/schema.json",
 | 
			
		||||
  "index": "/index.html",
 | 
			
		||||
  "assetGroups": [
 | 
			
		||||
    {
 | 
			
		||||
      "name": "app",
 | 
			
		||||
      "installMode": "prefetch",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "files": [
 | 
			
		||||
          "/favicon.ico",
 | 
			
		||||
          "/index.html",
 | 
			
		||||
          "/manifest.webmanifest",
 | 
			
		||||
          "/*.css",
 | 
			
		||||
          "/*.js"
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "assets",
 | 
			
		||||
      "installMode": "lazy",
 | 
			
		||||
      "updateMode": "prefetch",
 | 
			
		||||
      "resources": {
 | 
			
		||||
        "files": [
 | 
			
		||||
          "/assets/**",
 | 
			
		||||
          "/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)"
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@ -30,6 +30,7 @@
 | 
			
		||||
    "@angular/platform-browser": "~17.1.0",
 | 
			
		||||
    "@angular/platform-browser-dynamic": "~17.1.0",
 | 
			
		||||
    "@angular/router": "~17.1.0",
 | 
			
		||||
    "@angular/service-worker": "~17.1.0",
 | 
			
		||||
    "bootstrap-icons": "~1.8.0",
 | 
			
		||||
    "rxjs": "~7.8.0",
 | 
			
		||||
    "tslib": "^2.0.0",
 | 
			
		||||
 | 
			
		||||
@ -25,9 +25,6 @@ const routes: Routes = [
 | 
			
		||||
    loadChildren: () =>
 | 
			
		||||
      import('@abp/ng.setting-management').then(m => m.SettingManagementModule.forLazy()),
 | 
			
		||||
  },
 | 
			
		||||
  { path: 'books', loadChildren: () => import('./book/book.module').then(m => m.BookModule) },
 | 
			
		||||
  { path: 'customer', loadChildren: () => import('./customer/customer.module').then(m => m.CustomerModule) },
 | 
			
		||||
  { path: 'book-issue', loadChildren: () => import('./book-issue/book-issue.module').then(m => m.BookIssueModule) },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ import { AbpOAuthModule } from '@abp/ng.oauth';
 | 
			
		||||
import { ThemeLeptonXModule } from '@abp/ng.theme.lepton-x';
 | 
			
		||||
import { SideMenuLayoutModule } from '@abp/ng.theme.lepton-x/layouts';
 | 
			
		||||
import { AccountLayoutModule } from '@abp/ng.theme.lepton-x/account';
 | 
			
		||||
import { ServiceWorkerModule } from '@angular/service-worker';
 | 
			
		||||
@NgModule({
 | 
			
		||||
  imports: [
 | 
			
		||||
    BrowserModule,
 | 
			
		||||
@ -39,7 +40,13 @@ import { AccountLayoutModule } from '@abp/ng.theme.lepton-x/account';
 | 
			
		||||
    InternetConnectionStatusComponent,
 | 
			
		||||
    ThemeLeptonXModule.forRoot(),
 | 
			
		||||
    SideMenuLayoutModule.forRoot(),
 | 
			
		||||
    AccountLayoutModule.forRoot()
 | 
			
		||||
    AccountLayoutModule.forRoot(),
 | 
			
		||||
    ServiceWorkerModule.register('ngsw-worker.js', {
 | 
			
		||||
      enabled: environment.production,
 | 
			
		||||
      // Register the ServiceWorker as soon as the application is stable
 | 
			
		||||
      // or after 30 seconds (whichever comes first).
 | 
			
		||||
      registrationStrategy: 'registerWhenStable:30000'
 | 
			
		||||
    })
 | 
			
		||||
  ],
 | 
			
		||||
  declarations: [AppComponent],
 | 
			
		||||
  providers: [APP_ROUTE_PROVIDER],
 | 
			
		||||
 | 
			
		||||
@ -1,12 +0,0 @@
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
import { RouterModule, Routes } from '@angular/router';
 | 
			
		||||
import { BookIssueComponent } from './book-issue.component';
 | 
			
		||||
import { authGuard, permissionGuard } from '@abp/ng.core';
 | 
			
		||||
 | 
			
		||||
const routes: Routes = [{ path: '', component: BookIssueComponent,canActivate: [authGuard, permissionGuard] }];
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  imports: [RouterModule.forChild(routes)],
 | 
			
		||||
  exports: [RouterModule]
 | 
			
		||||
})
 | 
			
		||||
export class BookIssueRoutingModule { }
 | 
			
		||||
@ -1,97 +0,0 @@
 | 
			
		||||
<div class="card">
 | 
			
		||||
    <div class="card-header">
 | 
			
		||||
      <div class="row">
 | 
			
		||||
        <div class="col col-md-6">
 | 
			
		||||
          <h5 class="card-title">
 | 
			
		||||
            {{ 'Book-Issue' | abpLocalization }}
 | 
			
		||||
          </h5>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="text-end col col-md-6">
 | 
			
		||||
 | 
			
		||||
              <!-- Add the "new book" button here -->
 | 
			
		||||
        <div class="text-lg-end pt-2">
 | 
			
		||||
            <button id="create" class="btn btn-primary" type="button" (click)="createBookIssue()">
 | 
			
		||||
              <i class="fa fa-plus me-1"></i>
 | 
			
		||||
              <span>{{ "New Book Issue" | abpLocalization }}</span>
 | 
			
		||||
            </button>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="card-body">
 | 
			
		||||
      <ngx-datatable [rows]="bookIssueList.items" [count]="bookIssueList.totalCount" [list]="list" default> 
 | 
			
		||||
      
 | 
			
		||||
        <ngx-datatable-column
 | 
			
		||||
        [name]="'::Actions' | abpLocalization"
 | 
			
		||||
        [maxWidth]="150"
 | 
			
		||||
        [sortable]="false"
 | 
			
		||||
      >
 | 
			
		||||
        <ng-template let-row="row" ngx-datatable-cell-template>
 | 
			
		||||
          <div ngbDropdown container="body" class="d-inline-block">
 | 
			
		||||
            <button
 | 
			
		||||
              class="btn btn-primary btn-sm dropdown-toggle"
 | 
			
		||||
              data-toggle="dropdown"
 | 
			
		||||
              aria-haspopup="true"
 | 
			
		||||
              ngbDropdownToggle
 | 
			
		||||
            >
 | 
			
		||||
              <i class="fa fa-cog me-1"></i>{{ '::Actions' | abpLocalization }}
 | 
			
		||||
            </button>
 | 
			
		||||
            <div ngbDropdownMenu> 
 | 
			
		||||
              <button ngbDropdownItem (click)="delete(row.bookIssueId)">
 | 
			
		||||
                  {{ 'un Issue' | abpLocalization }}
 | 
			
		||||
              </button>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
      </ngx-datatable-column>
 | 
			
		||||
 | 
			
		||||
        <ngx-datatable-column [name]="'Book Name' | abpLocalization" prop="bookName"></ngx-datatable-column>
 | 
			
		||||
        <ngx-datatable-column [name]="'Customer Name' | abpLocalization" prop="customerName"> 
 | 
			
		||||
        </ngx-datatable-column>
 | 
			
		||||
        <ngx-datatable-column [name]="'Issue Date' | abpLocalization" prop="issueDate"> 
 | 
			
		||||
          <ng-template let-row="row" ngx-datatable-cell-template>
 | 
			
		||||
            {{ row.issueDate | date }}
 | 
			
		||||
          </ng-template>
 | 
			
		||||
        </ngx-datatable-column> 
 | 
			
		||||
      </ngx-datatable>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
  <!-- Add the modal here -->
 | 
			
		||||
<abp-modal [(visible)]="isModalOpen">
 | 
			
		||||
    <ng-template #abpHeader> 
 | 
			
		||||
      <h3> Book Issued </h3>
 | 
			
		||||
    </ng-template> 
 | 
			
		||||
    <ng-template #abpBody>
 | 
			
		||||
        <form [formGroup]="form" (ngSubmit)="save()">
 | 
			
		||||
          <div class="mt-2">
 | 
			
		||||
            <label for="book-type">Book Name</label><span> * </span>
 | 
			
		||||
            <select class="form-control" id="book-type" formControlName="bookId">
 | 
			
		||||
              <option [ngValue]="null">Select a book name</option>
 | 
			
		||||
              <option [ngValue]="book.id" *ngFor="let book of dropDownbook"> {{ book.name }}</option>
 | 
			
		||||
            </select>
 | 
			
		||||
          </div>
 | 
			
		||||
       
 | 
			
		||||
          <div class="mt-2">
 | 
			
		||||
            <label for="customer-name">Customer Name</label><span> * </span>
 | 
			
		||||
            <select class="form-control" id="customer-name" formControlName="customerId">
 | 
			
		||||
              <option [ngValue]="null">Select a customer name</option>
 | 
			
		||||
              <option [ngValue]="customer.id" *ngFor="let customer of dropDownCustomer"> {{ customer.firstName }} {{ customer.lastName}}</option>
 | 
			
		||||
            </select>
 | 
			
		||||
          </div> 
 | 
			
		||||
        </form>
 | 
			
		||||
      </ng-template>
 | 
			
		||||
      
 | 
			
		||||
  
 | 
			
		||||
    <ng-template #abpFooter>
 | 
			
		||||
        <button type="button" class="btn btn-secondary" abpClose>
 | 
			
		||||
            {{ '::Close' | abpLocalization }}
 | 
			
		||||
        </button>
 | 
			
		||||
      
 | 
			
		||||
        <!--added save button-->
 | 
			
		||||
        <button class="btn btn-primary" (click)="save()" [disabled]="form.invalid">
 | 
			
		||||
              <i class="fa fa-check mr-1"></i>
 | 
			
		||||
              {{ '::Save' | abpLocalization }}
 | 
			
		||||
        </button>
 | 
			
		||||
    </ng-template>
 | 
			
		||||
  </abp-modal>
 | 
			
		||||
@ -1,23 +0,0 @@
 | 
			
		||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
 | 
			
		||||
 | 
			
		||||
import { BookIssueComponent } from './book-issue.component';
 | 
			
		||||
 | 
			
		||||
describe('BookIssueComponent', () => {
 | 
			
		||||
  let component: BookIssueComponent;
 | 
			
		||||
  let fixture: ComponentFixture<BookIssueComponent>;
 | 
			
		||||
 | 
			
		||||
  beforeEach(async () => {
 | 
			
		||||
    await TestBed.configureTestingModule({
 | 
			
		||||
      declarations: [BookIssueComponent]
 | 
			
		||||
    })
 | 
			
		||||
    .compileComponents();
 | 
			
		||||
    
 | 
			
		||||
    fixture = TestBed.createComponent(BookIssueComponent);
 | 
			
		||||
    component = fixture.componentInstance;
 | 
			
		||||
    fixture.detectChanges();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should create', () => {
 | 
			
		||||
    expect(component).toBeTruthy();
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@ -1,83 +0,0 @@
 | 
			
		||||
import { Component, OnInit } from '@angular/core'; 
 | 
			
		||||
import { ListService, PagedResultDto } from '@abp/ng.core';
 | 
			
		||||
import { BookIssueDto, BookIssueListDto, BookIssueService } from '@proxy/book-issued';
 | 
			
		||||
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
 | 
			
		||||
import { BookDto, BookService } from '@proxy/books';
 | 
			
		||||
import { CustomerDto, CustomerService } from '@proxy/customers';
 | 
			
		||||
import { ConfirmationService,Confirmation } from '@abp/ng.theme.shared';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-book-issue',
 | 
			
		||||
  templateUrl: './book-issue.component.html',
 | 
			
		||||
  styleUrl: './book-issue.component.scss',
 | 
			
		||||
  providers: [ListService]
 | 
			
		||||
})
 | 
			
		||||
export class BookIssueComponent implements OnInit {
 | 
			
		||||
  isModalOpen = false;
 | 
			
		||||
 | 
			
		||||
  form:FormGroup;
 | 
			
		||||
  dropDownbook= {} as Array<BookDto>;
 | 
			
		||||
  dropDownCustomer= {} as Array<CustomerDto>;
 | 
			
		||||
  bookIssueList = { items: [], totalCount: 0 } as PagedResultDto<BookIssueListDto>; 
 | 
			
		||||
 | 
			
		||||
  constructor(public readonly list: ListService,
 | 
			
		||||
    private bookIssuedService: BookIssueService,
 | 
			
		||||
    private bookService: BookService,
 | 
			
		||||
    private customerService: CustomerService,
 | 
			
		||||
    private fb: FormBuilder,
 | 
			
		||||
    private confirmation: ConfirmationService ) {}
 | 
			
		||||
 
 | 
			
		||||
    ngOnInit(): void {
 | 
			
		||||
     this.dropdowninitiale();
 | 
			
		||||
     
 | 
			
		||||
    const bookStreamCreator = (query) => this.bookIssuedService.getList(query);
 | 
			
		||||
 | 
			
		||||
    this.list.hookToQuery(bookStreamCreator).subscribe((response) => {
 | 
			
		||||
      this.bookIssueList = response;
 | 
			
		||||
    });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    createBookIssue() {
 | 
			
		||||
      this.buildForm();
 | 
			
		||||
      this.isModalOpen = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buildForm() {
 | 
			
		||||
   
 | 
			
		||||
      this.form = this.fb.group({
 | 
			
		||||
        bookId: ['', Validators.required],
 | 
			
		||||
        customerId: ['', Validators.required],
 | 
			
		||||
      }); 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    save() {
 | 
			
		||||
      if (this.form.invalid) {
 | 
			
		||||
        return;
 | 
			
		||||
      } 
 | 
			
		||||
      this.bookIssuedService.create(this.form.value).subscribe(() => {
 | 
			
		||||
        this.isModalOpen = false;
 | 
			
		||||
        this.form.reset();
 | 
			
		||||
        this.list.get();
 | 
			
		||||
      });
 | 
			
		||||
    
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 dropdowninitiale(){
 | 
			
		||||
  this.bookService.getBookDropDown().subscribe((response)=>{
 | 
			
		||||
    this.dropDownbook = response;
 | 
			
		||||
 | 
			
		||||
  });
 | 
			
		||||
  this.customerService.getcustomerDropDown().subscribe((response)=>{
 | 
			
		||||
    this.dropDownCustomer = response;
 | 
			
		||||
 | 
			
		||||
  });
 | 
			
		||||
 }
 | 
			
		||||
 delete(bookIssueId: number) {
 | 
			
		||||
  this.confirmation.warn('::AreYouSureToUnIssue', '::AreYouSure').subscribe((status) => {
 | 
			
		||||
    if (status === Confirmation.Status.confirm) {
 | 
			
		||||
      this.bookIssuedService.delete(bookIssueId).subscribe(() => this.list.get());
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
import { CommonModule } from '@angular/common';
 | 
			
		||||
 | 
			
		||||
import { BookIssueRoutingModule } from './book-issue-routing.module';
 | 
			
		||||
import { BookIssueComponent } from './book-issue.component';
 | 
			
		||||
 | 
			
		||||
import{SharedModule} from '../shared/shared.module';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  declarations: [
 | 
			
		||||
    BookIssueComponent
 | 
			
		||||
  ],
 | 
			
		||||
  imports: [
 | 
			
		||||
    CommonModule,
 | 
			
		||||
    BookIssueRoutingModule,
 | 
			
		||||
    SharedModule
 | 
			
		||||
  ]
 | 
			
		||||
})
 | 
			
		||||
export class BookIssueModule { }
 | 
			
		||||
@ -1,12 +0,0 @@
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
import { RouterModule, Routes } from '@angular/router';
 | 
			
		||||
import { BookComponent } from './book.component'; 
 | 
			
		||||
import { authGuard, permissionGuard } from '@abp/ng.core';
 | 
			
		||||
 | 
			
		||||
const routes: Routes = [{ path: '', component: BookComponent, canActivate: [authGuard, permissionGuard] }];
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  imports: [RouterModule.forChild(routes)],
 | 
			
		||||
  exports: [RouterModule]
 | 
			
		||||
})
 | 
			
		||||
export class BookRoutingModule { }
 | 
			
		||||
@ -1,122 +0,0 @@
 | 
			
		||||
<div class="card">
 | 
			
		||||
    <div class="card-header">
 | 
			
		||||
      <div class="row">
 | 
			
		||||
        <div class="col col-md-6">
 | 
			
		||||
          <h5 class="card-title">
 | 
			
		||||
            {{ '::Menu:Books' | abpLocalization }}
 | 
			
		||||
          </h5>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="text-end col col-md-6">
 | 
			
		||||
          
 | 
			
		||||
          <!-- Add the "new book" button here -->
 | 
			
		||||
          <div class="text-lg-end pt-2">
 | 
			
		||||
            <button id="create" class="btn btn-primary" type="button" (click)="createBook()">
 | 
			
		||||
              <i class="fa fa-plus me-1"></i>
 | 
			
		||||
              <span>{{ "::NewBook" | abpLocalization }}</span>
 | 
			
		||||
            </button>
 | 
			
		||||
          </div>
 | 
			
		||||
            
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="card-body">
 | 
			
		||||
      <ngx-datatable [rows]="book.items" [count]="book.totalCount" [list]="list" default>
 | 
			
		||||
        <ngx-datatable-column
 | 
			
		||||
  [name]="'::Actions' | abpLocalization"
 | 
			
		||||
  [maxWidth]="150"
 | 
			
		||||
  [sortable]="false"
 | 
			
		||||
>
 | 
			
		||||
  <ng-template let-row="row" ngx-datatable-cell-template>
 | 
			
		||||
    <div ngbDropdown container="body" class="d-inline-block">
 | 
			
		||||
      <button
 | 
			
		||||
        class="btn btn-primary btn-sm dropdown-toggle"
 | 
			
		||||
        data-toggle="dropdown"
 | 
			
		||||
        aria-haspopup="true"
 | 
			
		||||
        ngbDropdownToggle
 | 
			
		||||
      >
 | 
			
		||||
        <i class="fa fa-cog me-1"></i>{{ '::Actions' | abpLocalization }}
 | 
			
		||||
      </button>
 | 
			
		||||
      <div ngbDropdownMenu>
 | 
			
		||||
        <button ngbDropdownItem (click)="editBook(row.id)">
 | 
			
		||||
          {{ '::Edit' | abpLocalization }}
 | 
			
		||||
        </button>
 | 
			
		||||
        <button ngbDropdownItem (click)="delete(row.id)">
 | 
			
		||||
          {{ '::Delete' | abpLocalization }}
 | 
			
		||||
      </button>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ng-template>
 | 
			
		||||
</ngx-datatable-column>
 | 
			
		||||
        <ngx-datatable-column [name]="'::Name' | abpLocalization" prop="name"></ngx-datatable-column>
 | 
			
		||||
        <ngx-datatable-column [name]="'::Type' | abpLocalization" prop="type">
 | 
			
		||||
          <ng-template let-row="row" ngx-datatable-cell-template>
 | 
			
		||||
            {{ '::Enum:BookType.' + row.type | abpLocalization }}
 | 
			
		||||
          </ng-template>
 | 
			
		||||
        </ngx-datatable-column>
 | 
			
		||||
        <ngx-datatable-column [name]="'::PublishDate' | abpLocalization" prop="publishDate">
 | 
			
		||||
          <ng-template let-row="row" ngx-datatable-cell-template>
 | 
			
		||||
            {{ row.publishDate | date }}
 | 
			
		||||
          </ng-template>
 | 
			
		||||
        </ngx-datatable-column>
 | 
			
		||||
        <ngx-datatable-column [name]="'::Price' | abpLocalization" prop="price">
 | 
			
		||||
          <ng-template let-row="row" ngx-datatable-cell-template>
 | 
			
		||||
            {{ row.price | currency }}
 | 
			
		||||
          </ng-template>
 | 
			
		||||
        </ngx-datatable-column>
 | 
			
		||||
      </ngx-datatable>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
  
 | 
			
		||||
  <!-- Add the modal here -->
 | 
			
		||||
<abp-modal [(visible)]="isModalOpen">
 | 
			
		||||
  <ng-template #abpHeader>
 | 
			
		||||
    <h3>{{ '::NewBook' | abpLocalization }}</h3>
 | 
			
		||||
  </ng-template>
 | 
			
		||||
 | 
			
		||||
  <ng-template #abpBody>
 | 
			
		||||
    <form [formGroup]="form" (ngSubmit)="save()">
 | 
			
		||||
      <div class="mt-2">
 | 
			
		||||
        <label for="book-name">Name</label><span> * </span>
 | 
			
		||||
        <input type="text" id="book-name" class="form-control" formControlName="name" autofocus />
 | 
			
		||||
      </div>
 | 
			
		||||
  
 | 
			
		||||
      <div class="mt-2">
 | 
			
		||||
        <label for="book-price">Price</label><span> * </span>
 | 
			
		||||
        <input type="number" id="book-price" class="form-control" formControlName="price" />
 | 
			
		||||
      </div>
 | 
			
		||||
  
 | 
			
		||||
      <div class="mt-2">
 | 
			
		||||
        <label for="book-type">Type</label><span> * </span>
 | 
			
		||||
        <select class="form-control" id="book-type" formControlName="type">
 | 
			
		||||
          <option [ngValue]="null">Select a book type</option>
 | 
			
		||||
          <option [ngValue]="type.value" *ngFor="let type of bookTypes"> {{ '::Enum:BookType.' + type.value | abpLocalization }}</option>
 | 
			
		||||
        </select>
 | 
			
		||||
      </div>
 | 
			
		||||
  
 | 
			
		||||
      <div class="mt-2">
 | 
			
		||||
        <label>Publish date</label><span> * </span>
 | 
			
		||||
        <input
 | 
			
		||||
          #datepicker="ngbDatepicker"
 | 
			
		||||
          class="form-control"
 | 
			
		||||
          name="datepicker"
 | 
			
		||||
          formControlName="publishDate"
 | 
			
		||||
          ngbDatepicker
 | 
			
		||||
          (click)="datepicker.toggle()"
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
    </form>
 | 
			
		||||
  </ng-template>
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  <ng-template #abpFooter>
 | 
			
		||||
    <button type="button" class="btn btn-secondary" abpClose>
 | 
			
		||||
      {{ '::Close' | abpLocalization }}
 | 
			
		||||
  </button>
 | 
			
		||||
 | 
			
		||||
  <!--added save button-->
 | 
			
		||||
  <button class="btn btn-primary" (click)="save()" [disabled]="form.invalid">
 | 
			
		||||
        <i class="fa fa-check mr-1"></i>
 | 
			
		||||
        {{ '::Save' | abpLocalization }}
 | 
			
		||||
  </button>
 | 
			
		||||
  </ng-template>
 | 
			
		||||
</abp-modal>
 | 
			
		||||
@ -1,23 +0,0 @@
 | 
			
		||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
 | 
			
		||||
 | 
			
		||||
import { BookComponent } from './book.component';
 | 
			
		||||
 | 
			
		||||
describe('BookComponent', () => {
 | 
			
		||||
  let component: BookComponent;
 | 
			
		||||
  let fixture: ComponentFixture<BookComponent>;
 | 
			
		||||
 | 
			
		||||
  beforeEach(async () => {
 | 
			
		||||
    await TestBed.configureTestingModule({
 | 
			
		||||
      declarations: [BookComponent]
 | 
			
		||||
    })
 | 
			
		||||
    .compileComponents();
 | 
			
		||||
    
 | 
			
		||||
    fixture = TestBed.createComponent(BookComponent);
 | 
			
		||||
    component = fixture.componentInstance;
 | 
			
		||||
    fixture.detectChanges();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should create', () => {
 | 
			
		||||
    expect(component).toBeTruthy();
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@ -1,88 +0,0 @@
 | 
			
		||||
import { ListService, PagedResultDto } from '@abp/ng.core';
 | 
			
		||||
import { Component, OnInit } from '@angular/core';
 | 
			
		||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 | 
			
		||||
import { BookService, BookDto, bookTypeOptions } from '@proxy/books';
 | 
			
		||||
import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap';
 | 
			
		||||
import { ConfirmationService, Confirmation } from '@abp/ng.theme.shared';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-book',
 | 
			
		||||
  templateUrl: './book.component.html',
 | 
			
		||||
  styleUrls: ['./book.component.scss'],
 | 
			
		||||
  providers: [ListService,
 | 
			
		||||
    { provide: NgbDateAdapter, useClass: NgbDateNativeAdapter } // add this line
 | 
			
		||||
  ],
 | 
			
		||||
})
 | 
			
		||||
export class BookComponent implements OnInit {
 | 
			
		||||
  book = { items: [], totalCount: 0 } as PagedResultDto<BookDto>; 
 | 
			
		||||
  selectedBook = {} as BookDto; // declare selectedBook
 | 
			
		||||
  isModalOpen = false; // add this line
 | 
			
		||||
  form: FormGroup; // add this line
 | 
			
		||||
  bookTypes = bookTypeOptions;
 | 
			
		||||
 | 
			
		||||
  constructor(public readonly list: ListService, private bookService: BookService, private fb: FormBuilder,
 | 
			
		||||
    private confirmation: ConfirmationService 
 | 
			
		||||
  ) {}
 | 
			
		||||
 | 
			
		||||
  ngOnInit() {
 | 
			
		||||
    debugger;
 | 
			
		||||
     
 | 
			
		||||
    const bookStreamCreator = (query) => this.bookService.getList(query);
 | 
			
		||||
 | 
			
		||||
    this.list.hookToQuery(bookStreamCreator).subscribe((response) => {
 | 
			
		||||
      this.book = response;
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  // add new method
 | 
			
		||||
  createBook() {
 | 
			
		||||
    this.buildForm(); // add this line
 | 
			
		||||
    this.selectedBook = {} as BookDto; // reset the selected book
 | 
			
		||||
 | 
			
		||||
    this.isModalOpen = true;
 | 
			
		||||
  }
 | 
			
		||||
  buildForm() {
 | 
			
		||||
    this.form = this.fb.group({
 | 
			
		||||
      name: ['', Validators.required],
 | 
			
		||||
      type: [null, Validators.required],
 | 
			
		||||
      publishDate: [null, Validators.required],
 | 
			
		||||
      price: [null, Validators.required],
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  save() {
 | 
			
		||||
    if (this.form.invalid) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    const request = this.selectedBook.id
 | 
			
		||||
    ? this.bookService.update(this.selectedBook.id, this.form.value)
 | 
			
		||||
    : this.bookService.create(this.form.value);
 | 
			
		||||
 | 
			
		||||
  request.subscribe(() => {
 | 
			
		||||
    this.isModalOpen = false;
 | 
			
		||||
    this.form.reset();
 | 
			
		||||
    this.list.get();
 | 
			
		||||
  });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    // Add editBook method
 | 
			
		||||
    editBook(id: string) {
 | 
			
		||||
      this.bookService.get(id).subscribe((book) => {
 | 
			
		||||
        this.selectedBook = book;
 | 
			
		||||
        this.buildForm();
 | 
			
		||||
        this.form.controls["name"].setValue(this.selectedBook.name);
 | 
			
		||||
        this.form.controls["type"].setValue(this.selectedBook.type);
 | 
			
		||||
        this.form.controls["publishDate"].setValue(this.selectedBook.publishDate);
 | 
			
		||||
        this.form.controls["price"].setValue(this.selectedBook.price);
 | 
			
		||||
        this.isModalOpen = true;
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    delete(id: string) {
 | 
			
		||||
      this.confirmation.warn('::AreYouSureToDelete', '::AreYouSure').subscribe((status) => {
 | 
			
		||||
        if (status === Confirmation.Status.confirm) {
 | 
			
		||||
          this.bookService.delete(id).subscribe(() => this.list.get());
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
import { CommonModule } from '@angular/common';
 | 
			
		||||
 | 
			
		||||
import { BookRoutingModule } from './book-routing.module';
 | 
			
		||||
import { BookComponent } from './book.component';
 | 
			
		||||
import{SharedModule} from '../shared/shared.module';
 | 
			
		||||
import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap'; // add this line
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  declarations: [
 | 
			
		||||
    BookComponent
 | 
			
		||||
  ],
 | 
			
		||||
  imports: [
 | 
			
		||||
    CommonModule,
 | 
			
		||||
    BookRoutingModule,
 | 
			
		||||
    SharedModule,
 | 
			
		||||
    NgbDatepickerModule
 | 
			
		||||
  ]
 | 
			
		||||
})
 | 
			
		||||
export class BookModule { }
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
import { RouterModule, Routes } from '@angular/router';
 | 
			
		||||
import { CustomerComponent } from './customer.component';
 | 
			
		||||
import { authGuard, permissionGuard } from '@abp/ng.core';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const routes: Routes = [{ path: '', component: CustomerComponent,canActivate: [authGuard, permissionGuard] }];
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  imports: [RouterModule.forChild(routes)],
 | 
			
		||||
  exports: [RouterModule]
 | 
			
		||||
})
 | 
			
		||||
export class CustomerRoutingModule { }
 | 
			
		||||
@ -1,101 +0,0 @@
 | 
			
		||||
<div class="card">
 | 
			
		||||
    <div class="card-header">
 | 
			
		||||
      <div class="row">
 | 
			
		||||
        <div class="col col-md-6">
 | 
			
		||||
          <h5 class="card-title">
 | 
			
		||||
            {{ 'customer' | abpLocalization }}
 | 
			
		||||
          </h5>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="text-end col col-md-6">
 | 
			
		||||
 | 
			
		||||
              <!-- Add the "new book" button here -->
 | 
			
		||||
        <div class="text-lg-end pt-2">
 | 
			
		||||
            <button id="create" class="btn btn-primary" type="button" (click)="createCustomer()">
 | 
			
		||||
              <i class="fa fa-plus me-1"></i>
 | 
			
		||||
              <span>{{ "New Customer" | abpLocalization }}</span>
 | 
			
		||||
            </button>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="card-body">
 | 
			
		||||
      <ngx-datatable [rows]="customer.items" [count]="customer.totalCount" [list]="list" default>
 | 
			
		||||
        <ngx-datatable-column
 | 
			
		||||
  [name]="'::Actions' | abpLocalization"
 | 
			
		||||
  [maxWidth]="150"
 | 
			
		||||
  [sortable]="false"
 | 
			
		||||
>
 | 
			
		||||
  <ng-template let-row="row" ngx-datatable-cell-template>
 | 
			
		||||
    <div ngbDropdown container="body" class="d-inline-block">
 | 
			
		||||
      <button
 | 
			
		||||
        class="btn btn-primary btn-sm dropdown-toggle"
 | 
			
		||||
        data-toggle="dropdown"
 | 
			
		||||
        aria-haspopup="true"
 | 
			
		||||
        ngbDropdownToggle
 | 
			
		||||
      >
 | 
			
		||||
        <i class="fa fa-cog me-1"></i>{{ '::Actions' | abpLocalization }}
 | 
			
		||||
      </button>
 | 
			
		||||
      <div ngbDropdownMenu>
 | 
			
		||||
        <button ngbDropdownItem (click)="editCustomer(row.id)">
 | 
			
		||||
          {{ '::Edit' | abpLocalization }}
 | 
			
		||||
        </button>
 | 
			
		||||
        <button ngbDropdownItem (click)="delete(row.id)">
 | 
			
		||||
            {{ '::Delete' | abpLocalization }}
 | 
			
		||||
        </button>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ng-template>
 | 
			
		||||
</ngx-datatable-column>
 | 
			
		||||
        <ngx-datatable-column [name]="'first Name' | abpLocalization" prop="firstName"></ngx-datatable-column>
 | 
			
		||||
        <ngx-datatable-column [name]="'Last Name' | abpLocalization" prop="lastName"> 
 | 
			
		||||
        </ngx-datatable-column>
 | 
			
		||||
        <ngx-datatable-column [name]="'::Address' | abpLocalization" prop="address"> 
 | 
			
		||||
        </ngx-datatable-column>
 | 
			
		||||
        <ngx-datatable-column [name]="'::Phone' | abpLocalization" prop="phone"> 
 | 
			
		||||
        </ngx-datatable-column>
 | 
			
		||||
      </ngx-datatable>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
  <!-- Add the modal here -->
 | 
			
		||||
<abp-modal [(visible)]="isModalOpen">
 | 
			
		||||
    <ng-template #abpHeader> 
 | 
			
		||||
      <h3>{{ (selectedcustomer.id ? '::Edit' : '::New Customer' ) | abpLocalization }}</h3>
 | 
			
		||||
    </ng-template> 
 | 
			
		||||
    <ng-template #abpBody>
 | 
			
		||||
        <form [formGroup]="form" (ngSubmit)="save()">
 | 
			
		||||
          <div class="mt-2">
 | 
			
		||||
            <label for="customer-first-name">First Name</label><span> * </span>
 | 
			
		||||
            <input type="text" id="customer-first-name" class="form-control" formControlName="firstName" autofocus />
 | 
			
		||||
          </div>
 | 
			
		||||
       
 | 
			
		||||
          <div class="mt-2">
 | 
			
		||||
            <label for="customer-last-name">Last Name</label><span> * </span>
 | 
			
		||||
            <input type="text" id="customer-last-name" class="form-control" formControlName="lastName"  />
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          <div class="mt-2">
 | 
			
		||||
            <label for="customer-phone-name">Phone</label><span> * </span>
 | 
			
		||||
            <input type="text" id="customer-phone-name" class="form-control" formControlName="phone"  />
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          <div class="mt-2">
 | 
			
		||||
            <label for="customer-address-name">Address</label><span> * </span>
 | 
			
		||||
            <input type="text" id="customer-address-name" class="form-control" formControlName="address"  />
 | 
			
		||||
          </div>
 | 
			
		||||
        </form>
 | 
			
		||||
      </ng-template>
 | 
			
		||||
      
 | 
			
		||||
  
 | 
			
		||||
    <ng-template #abpFooter>
 | 
			
		||||
        <button type="button" class="btn btn-secondary" abpClose>
 | 
			
		||||
            {{ '::Close' | abpLocalization }}
 | 
			
		||||
        </button>
 | 
			
		||||
      
 | 
			
		||||
        <!--added save button-->
 | 
			
		||||
        <button class="btn btn-primary" (click)="save()" [disabled]="form.invalid">
 | 
			
		||||
              <i class="fa fa-check mr-1"></i>
 | 
			
		||||
              {{ '::Save' | abpLocalization }}
 | 
			
		||||
        </button>
 | 
			
		||||
    </ng-template>
 | 
			
		||||
  </abp-modal>
 | 
			
		||||
@ -1,23 +0,0 @@
 | 
			
		||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
 | 
			
		||||
 | 
			
		||||
import { CustomerComponent } from './customer.component';
 | 
			
		||||
 | 
			
		||||
describe('CustomerComponent', () => {
 | 
			
		||||
  let component: CustomerComponent;
 | 
			
		||||
  let fixture: ComponentFixture<CustomerComponent>;
 | 
			
		||||
 | 
			
		||||
  beforeEach(async () => {
 | 
			
		||||
    await TestBed.configureTestingModule({
 | 
			
		||||
      declarations: [CustomerComponent]
 | 
			
		||||
    })
 | 
			
		||||
    .compileComponents();
 | 
			
		||||
    
 | 
			
		||||
    fixture = TestBed.createComponent(CustomerComponent);
 | 
			
		||||
    component = fixture.componentInstance;
 | 
			
		||||
    fixture.detectChanges();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should create', () => {
 | 
			
		||||
    expect(component).toBeTruthy();
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@ -1,92 +0,0 @@
 | 
			
		||||
import { Component, OnInit } from '@angular/core';
 | 
			
		||||
import { ListService, PagedResultDto } from '@abp/ng.core';
 | 
			
		||||
import { CustomerDto, CustomerService } from '@proxy/customers';
 | 
			
		||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms'; 
 | 
			
		||||
import { ConfirmationService, Confirmation } from '@abp/ng.theme.shared';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-customer',
 | 
			
		||||
  templateUrl: './customer.component.html',
 | 
			
		||||
  styleUrl: './customer.component.scss',
 | 
			
		||||
  providers: [ListService]
 | 
			
		||||
})
 | 
			
		||||
export class CustomerComponent implements OnInit {
 | 
			
		||||
  customer = { items: [], totalCount: 0 } as PagedResultDto<CustomerDto>; 
 | 
			
		||||
  isModalOpen = false;
 | 
			
		||||
  form: FormGroup;
 | 
			
		||||
  selectedcustomer = {} as CustomerDto;
 | 
			
		||||
  constructor(public readonly list: ListService,
 | 
			
		||||
     private customerService: CustomerService,
 | 
			
		||||
     private fb: FormBuilder,
 | 
			
		||||
     private confirmation: ConfirmationService ) {}
 | 
			
		||||
  
 | 
			
		||||
  ngOnInit() {
 | 
			
		||||
    debugger;
 | 
			
		||||
     
 | 
			
		||||
    const bookStreamCreator = (query) => this.customerService.getList(query);
 | 
			
		||||
 | 
			
		||||
    this.list.hookToQuery(bookStreamCreator).subscribe((response) => {
 | 
			
		||||
      this.customer = response;
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  // add new method
 | 
			
		||||
  createCustomer() {
 | 
			
		||||
    this.selectedcustomer = {} as CustomerDto; 
 | 
			
		||||
     this.buildForm();
 | 
			
		||||
    this.isModalOpen = true;
 | 
			
		||||
  }
 | 
			
		||||
  editCustomer(id: number) {
 | 
			
		||||
    this.customerService.get(id).subscribe((customer) => {
 | 
			
		||||
      debugger;
 | 
			
		||||
      this.selectedcustomer = customer;
 | 
			
		||||
      this.buildForm();  
 | 
			
		||||
      this.isModalOpen = true;
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  buildForm() {
 | 
			
		||||
   
 | 
			
		||||
    this.form = this.fb.group({
 | 
			
		||||
      firstName: [this.selectedcustomer.firstName || '', Validators.required],
 | 
			
		||||
      lastName: [this.selectedcustomer.lastName, Validators.required],
 | 
			
		||||
      phone: [this.selectedcustomer.phone, Validators.required],
 | 
			
		||||
      address: [this.selectedcustomer.address, Validators.required],
 | 
			
		||||
    }); 
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // add save method
 | 
			
		||||
  save() {
 | 
			
		||||
    if (this.form.invalid) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
debugger;
 | 
			
		||||
    const request = this.selectedcustomer.id
 | 
			
		||||
    ? this.customerService.update(this.selectedcustomer.id, this.form.value)
 | 
			
		||||
    : this.customerService.create(this.form.value);
 | 
			
		||||
if(this.selectedcustomer.id){
 | 
			
		||||
 | 
			
		||||
  this.customerService.update(this.selectedcustomer.id,this.form.value).subscribe(() => {
 | 
			
		||||
    this.isModalOpen = false;
 | 
			
		||||
    this.form.reset();
 | 
			
		||||
    this.list.get();
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
else{
 | 
			
		||||
  this.customerService.create(this.form.value).subscribe(() => {
 | 
			
		||||
    this.isModalOpen = false;
 | 
			
		||||
    this.form.reset();
 | 
			
		||||
    this.list.get();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  delete(id: number) {
 | 
			
		||||
    this.confirmation.warn('::AreYouSureToDelete', '::AreYouSure').subscribe((status) => {
 | 
			
		||||
      if (status === Confirmation.Status.confirm) {
 | 
			
		||||
        this.customerService.delete(id).subscribe(() => this.list.get());
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,20 +0,0 @@
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
import { CommonModule } from '@angular/common';
 | 
			
		||||
 | 
			
		||||
import { CustomerRoutingModule } from './customer-routing.module';
 | 
			
		||||
import { CustomerComponent } from './customer.component';
 | 
			
		||||
 | 
			
		||||
import{SharedModule} from '../shared/shared.module';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  declarations: [
 | 
			
		||||
    CustomerComponent
 | 
			
		||||
  ],
 | 
			
		||||
  imports: [
 | 
			
		||||
    CommonModule,
 | 
			
		||||
    CustomerRoutingModule,
 | 
			
		||||
    SharedModule
 | 
			
		||||
    
 | 
			
		||||
  ]
 | 
			
		||||
})
 | 
			
		||||
export class CustomerModule { }
 | 
			
		||||
@ -1,17 +0,0 @@
 | 
			
		||||
# Proxy Generation Output
 | 
			
		||||
 | 
			
		||||
This directory includes the output of the latest proxy generation.
 | 
			
		||||
The files and folders in it will be overwritten when proxy generation is run again.
 | 
			
		||||
Therefore, please do not place your own content in this folder.
 | 
			
		||||
 | 
			
		||||
In addition, `generate-proxy.json` works like a lock file.
 | 
			
		||||
It includes information used by the proxy generator, so please do not delete or modify it.
 | 
			
		||||
 | 
			
		||||
Finally, the name of the files and folders should not be changed for two reasons:
 | 
			
		||||
- Proxy generator will keep creating them at those paths and you will have multiple copies of the same content.
 | 
			
		||||
- ABP Suite generates files which include imports from this folder.
 | 
			
		||||
 | 
			
		||||
> **Important Notice:** If you are building a module and are planning to publish to npm,
 | 
			
		||||
> some of the generated proxies are likely to be exported from public-api.ts file. In such a case,
 | 
			
		||||
> please make sure you export files directly and not from barrel exports. In other words,
 | 
			
		||||
> do not include index.ts exports in your public-api.ts exports.
 | 
			
		||||
@ -1,56 +0,0 @@
 | 
			
		||||
import type { AuthorDto, CreateAuthorDto, GetAuthorListDto, UpdateAuthorDto } from './models';
 | 
			
		||||
import { RestService, Rest } from '@abp/ng.core';
 | 
			
		||||
import type { PagedResultDto } from '@abp/ng.core';
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
 | 
			
		||||
@Injectable({
 | 
			
		||||
  providedIn: 'root',
 | 
			
		||||
})
 | 
			
		||||
export class AuthorService {
 | 
			
		||||
  apiName = 'Default';
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  create = (input: CreateAuthorDto, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, AuthorDto>({
 | 
			
		||||
      method: 'POST',
 | 
			
		||||
      url: '/api/app/author',
 | 
			
		||||
      body: input,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  delete = (id: string, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, void>({
 | 
			
		||||
      method: 'DELETE',
 | 
			
		||||
      url: `/api/app/author/${id}`,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  get = (id: string, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, AuthorDto>({
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: `/api/app/author/${id}`,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  getList = (input: GetAuthorListDto, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, PagedResultDto<AuthorDto>>({
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/api/app/author',
 | 
			
		||||
      params: { filter: input.filter, sorting: input.sorting, skipCount: input.skipCount, maxResultCount: input.maxResultCount },
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  update = (id: string, input: UpdateAuthorDto, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, void>({
 | 
			
		||||
      method: 'PUT',
 | 
			
		||||
      url: `/api/app/author/${id}`,
 | 
			
		||||
      body: input,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
 | 
			
		||||
  constructor(private restService: RestService) {}
 | 
			
		||||
}
 | 
			
		||||
@ -1,2 +0,0 @@
 | 
			
		||||
export * from './author.service';
 | 
			
		||||
export * from './models';
 | 
			
		||||
@ -1,23 +0,0 @@
 | 
			
		||||
import type { EntityDto, PagedAndSortedResultRequestDto } from '@abp/ng.core';
 | 
			
		||||
 | 
			
		||||
export interface AuthorDto extends EntityDto<string> {
 | 
			
		||||
  name?: string;
 | 
			
		||||
  birthDate?: string;
 | 
			
		||||
  shortBio?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface CreateAuthorDto {
 | 
			
		||||
  name: string;
 | 
			
		||||
  birthDate: string;
 | 
			
		||||
  shortBio?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface GetAuthorListDto extends PagedAndSortedResultRequestDto {
 | 
			
		||||
  filter?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface UpdateAuthorDto {
 | 
			
		||||
  name: string;
 | 
			
		||||
  birthDate: string;
 | 
			
		||||
  shortBio?: string;
 | 
			
		||||
}
 | 
			
		||||
@ -1,55 +0,0 @@
 | 
			
		||||
import type { BookIssueDto, BookIssueListDto } from './models';
 | 
			
		||||
import { RestService, Rest } from '@abp/ng.core';
 | 
			
		||||
import type { PagedResultDto } from '@abp/ng.core';
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
 | 
			
		||||
@Injectable({
 | 
			
		||||
  providedIn: 'root',
 | 
			
		||||
})
 | 
			
		||||
export class BookIssueService {
 | 
			
		||||
  apiName = 'Default';
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  create = (input: BookIssueDto, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, BookIssueDto>({
 | 
			
		||||
      method: 'POST',
 | 
			
		||||
      url: '/api/app/book-issue',
 | 
			
		||||
      body: input,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  delete = (id: number, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, void>({
 | 
			
		||||
      method: 'DELETE',
 | 
			
		||||
      url: `/api/app/book-issue/${id}`,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  get = (id: number, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, BookIssueDto>({
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: `/api/app/book-issue/${id}`,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  getList = (config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, PagedResultDto<BookIssueListDto>>({
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/api/app/book-issue',
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  update = (id: number, input: BookIssueDto, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, void>({
 | 
			
		||||
      method: 'PUT',
 | 
			
		||||
      url: `/api/app/book-issue/${id}`,
 | 
			
		||||
      body: input,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
 | 
			
		||||
  constructor(private restService: RestService) {}
 | 
			
		||||
}
 | 
			
		||||
@ -1,2 +0,0 @@
 | 
			
		||||
export * from './book-issue.service';
 | 
			
		||||
export * from './models';
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
import type { EntityDto } from '@abp/ng.core';
 | 
			
		||||
 | 
			
		||||
export interface BookIssueDto extends EntityDto<number> {
 | 
			
		||||
  bookId?: string;
 | 
			
		||||
  customerId: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface BookIssueListDto {
 | 
			
		||||
  bookIssueId: number;
 | 
			
		||||
  bookName?: string;
 | 
			
		||||
  customerName?: string;
 | 
			
		||||
  issueDate?: string;
 | 
			
		||||
}
 | 
			
		||||
@ -1,15 +0,0 @@
 | 
			
		||||
import { mapEnumToOptions } from '@abp/ng.core';
 | 
			
		||||
 | 
			
		||||
export enum BookType {
 | 
			
		||||
  Undefined = 0,
 | 
			
		||||
  Adventure = 1,
 | 
			
		||||
  Biography = 2,
 | 
			
		||||
  Dystopia = 3,
 | 
			
		||||
  Fantastic = 4,
 | 
			
		||||
  Horror = 5,
 | 
			
		||||
  Science = 6,
 | 
			
		||||
  ScienceFiction = 7,
 | 
			
		||||
  Poetry = 8,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const bookTypeOptions = mapEnumToOptions(BookType);
 | 
			
		||||
@ -1,64 +0,0 @@
 | 
			
		||||
import type { BookDto, CreateUpdateBookDto } from './models';
 | 
			
		||||
import { RestService, Rest } from '@abp/ng.core';
 | 
			
		||||
import type { PagedAndSortedResultRequestDto, PagedResultDto } from '@abp/ng.core';
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
 | 
			
		||||
@Injectable({
 | 
			
		||||
  providedIn: 'root',
 | 
			
		||||
})
 | 
			
		||||
export class BookService {
 | 
			
		||||
  apiName = 'Default';
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  create = (input: CreateUpdateBookDto, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, BookDto>({
 | 
			
		||||
      method: 'POST',
 | 
			
		||||
      url: '/api/app/book',
 | 
			
		||||
      body: input,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  delete = (id: string, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, void>({
 | 
			
		||||
      method: 'DELETE',
 | 
			
		||||
      url: `/api/app/book/${id}`,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  get = (id: string, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, BookDto>({
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: `/api/app/book/${id}`,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  getBookDropDown = (config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, BookDto[]>({
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/api/app/book/book-drop-down',
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  getList = (input: PagedAndSortedResultRequestDto, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, PagedResultDto<BookDto>>({
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/api/app/book',
 | 
			
		||||
      params: { sorting: input.sorting, skipCount: input.skipCount, maxResultCount: input.maxResultCount },
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  update = (id: string, input: CreateUpdateBookDto, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, BookDto>({
 | 
			
		||||
      method: 'PUT',
 | 
			
		||||
      url: `/api/app/book/${id}`,
 | 
			
		||||
      body: input,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
 | 
			
		||||
  constructor(private restService: RestService) {}
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +0,0 @@
 | 
			
		||||
export * from './book-type.enum';
 | 
			
		||||
export * from './book.service';
 | 
			
		||||
export * from './models';
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
import type { AuditedEntityDto } from '@abp/ng.core';
 | 
			
		||||
import type { BookType } from './book-type.enum';
 | 
			
		||||
 | 
			
		||||
export interface BookDto extends AuditedEntityDto<string> {
 | 
			
		||||
  name?: string;
 | 
			
		||||
  type: BookType;
 | 
			
		||||
  publishDate?: string;
 | 
			
		||||
  price: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface CreateUpdateBookDto {
 | 
			
		||||
  name: string;
 | 
			
		||||
  type: BookType;
 | 
			
		||||
  publishDate: string;
 | 
			
		||||
  price: number;
 | 
			
		||||
}
 | 
			
		||||
@ -1,63 +0,0 @@
 | 
			
		||||
import type { CustomerDto } from './models';
 | 
			
		||||
import { RestService, Rest } from '@abp/ng.core';
 | 
			
		||||
import type { PagedResultDto } from '@abp/ng.core';
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
 | 
			
		||||
@Injectable({
 | 
			
		||||
  providedIn: 'root',
 | 
			
		||||
})
 | 
			
		||||
export class CustomerService {
 | 
			
		||||
  apiName = 'Default';
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  create = (input: CustomerDto, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, CustomerDto>({
 | 
			
		||||
      method: 'POST',
 | 
			
		||||
      url: '/api/app/customer',
 | 
			
		||||
      body: input,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  delete = (id: number, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, void>({
 | 
			
		||||
      method: 'DELETE',
 | 
			
		||||
      url: `/api/app/customer/${id}`,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  get = (id: number, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, CustomerDto>({
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: `/api/app/customer/${id}`,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  getList = (config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, PagedResultDto<CustomerDto>>({
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/api/app/customer',
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  getcustomerDropDown = (config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, CustomerDto[]>({
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/api/app/customer/customer-drop-down',
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  update = (id: number, input: CustomerDto, config?: Partial<Rest.Config>) =>
 | 
			
		||||
    this.restService.request<any, void>({
 | 
			
		||||
      method: 'PUT',
 | 
			
		||||
      url: `/api/app/customer/${id}`,
 | 
			
		||||
      body: input,
 | 
			
		||||
    },
 | 
			
		||||
    { apiName: this.apiName,...config });
 | 
			
		||||
 | 
			
		||||
  constructor(private restService: RestService) {}
 | 
			
		||||
}
 | 
			
		||||
@ -1,2 +0,0 @@
 | 
			
		||||
export * from './customer.service';
 | 
			
		||||
export * from './models';
 | 
			
		||||
@ -1,8 +0,0 @@
 | 
			
		||||
import type { EntityDto } from '@abp/ng.core';
 | 
			
		||||
 | 
			
		||||
export interface CustomerDto extends EntityDto<number> {
 | 
			
		||||
  firstName?: string;
 | 
			
		||||
  lastName?: string;
 | 
			
		||||
  phone?: string;
 | 
			
		||||
  address?: string;
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
import * as Authors from './authors';
 | 
			
		||||
import * as BookIssued from './book-issued';
 | 
			
		||||
import * as Books from './books';
 | 
			
		||||
import * as Customers from './customers';
 | 
			
		||||
export { Authors, BookIssued, Books, Customers };
 | 
			
		||||
@ -15,39 +15,6 @@ function configureRoutes(routesService: RoutesService) {
 | 
			
		||||
        order: 1,
 | 
			
		||||
        layout: eLayoutType.application,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        path: '/book-store',
 | 
			
		||||
        name: '::Menu:BookStore',
 | 
			
		||||
        iconClass: 'fas fa-book',
 | 
			
		||||
        order: 2,
 | 
			
		||||
        layout: eLayoutType.application,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        path: '/books',
 | 
			
		||||
        name: '::Menu:Books',
 | 
			
		||||
        parentName: '::Menu:BookStore',
 | 
			
		||||
        layout: eLayoutType.application,
 | 
			
		||||
        requiredPolicy: 'BookStore.Books',
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      {
 | 
			
		||||
        path: '/customer',
 | 
			
		||||
        name: 'Customer', 
 | 
			
		||||
        iconClass: 'fas fa-user',
 | 
			
		||||
        order: 2,
 | 
			
		||||
        layout: eLayoutType.application, 
 | 
			
		||||
        requiredPolicy: 'BookStore.Customers',
 | 
			
		||||
      }, 
 | 
			
		||||
      {
 | 
			
		||||
        path: '/book-issue',
 | 
			
		||||
        name: 'book-issue',
 | 
			
		||||
        iconClass: 'fas fa-book',
 | 
			
		||||
        order: 2, 
 | 
			
		||||
        layout: eLayoutType.application, 
 | 
			
		||||
        requiredPolicy: 'BookStore.BookIssued',
 | 
			
		||||
      },
 | 
			
		||||
    ]);
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								angular/src/assets/icons/icon-128x128.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								angular/src/assets/icons/icon-144x144.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								angular/src/assets/icons/icon-152x152.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								angular/src/assets/icons/icon-192x192.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								angular/src/assets/icons/icon-384x384.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								angular/src/assets/icons/icon-512x512.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								angular/src/assets/icons/icon-72x72.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 792 B  | 
							
								
								
									
										
											BIN
										
									
								
								angular/src/assets/icons/icon-96x96.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 958 B  | 
@ -10,7 +10,7 @@ export const environment = {
 | 
			
		||||
    logoUrl: '',
 | 
			
		||||
  },
 | 
			
		||||
  oAuthConfig: {
 | 
			
		||||
    issuer: 'https://localhost:44356/',
 | 
			
		||||
    issuer: 'https://localhost:44362/',
 | 
			
		||||
    redirectUri: baseUrl,
 | 
			
		||||
    clientId: 'BookStore_App',
 | 
			
		||||
    responseType: 'code',
 | 
			
		||||
@ -19,7 +19,7 @@ export const environment = {
 | 
			
		||||
  },
 | 
			
		||||
  apis: {
 | 
			
		||||
    default: {
 | 
			
		||||
      url: 'https://localhost:44356',
 | 
			
		||||
      url: 'https://localhost:44362',
 | 
			
		||||
      rootNamespace: 'Acme.BookStore',
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ export const environment = {
 | 
			
		||||
    logoUrl: '',
 | 
			
		||||
  },
 | 
			
		||||
  oAuthConfig: {
 | 
			
		||||
    issuer: 'https://localhost:44356/',
 | 
			
		||||
    issuer: 'https://localhost:44362/',
 | 
			
		||||
    redirectUri: baseUrl,
 | 
			
		||||
    clientId: 'BookStore_App',
 | 
			
		||||
    responseType: 'code',
 | 
			
		||||
@ -19,7 +19,7 @@ export const environment = {
 | 
			
		||||
  },
 | 
			
		||||
  apis: {
 | 
			
		||||
    default: {
 | 
			
		||||
      url: 'https://localhost:44356',
 | 
			
		||||
      url: 'https://localhost:44362',
 | 
			
		||||
      rootNamespace: 'Acme.BookStore',
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,19 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8" />
 | 
			
		||||
    <meta charset="utf-8"/>
 | 
			
		||||
    <title>BookStore</title>
 | 
			
		||||
    <base href="/" />
 | 
			
		||||
    <base href="/"/>
 | 
			
		||||
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1" />
 | 
			
		||||
    <link rel="icon" type="image/x-icon" href="favicon.ico" />
 | 
			
		||||
  </head>
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
 | 
			
		||||
    <link rel="icon" type="image/x-icon" href="favicon.ico"/>
 | 
			
		||||
    <link rel="manifest" href="manifest.webmanifest">
 | 
			
		||||
  <meta name="theme-color" content="#1976d2">
 | 
			
		||||
</head>
 | 
			
		||||
  <body class="bg-light">
 | 
			
		||||
    <app-root>
 | 
			
		||||
      <div class="donut centered"></div>
 | 
			
		||||
    </app-root>
 | 
			
		||||
  </body>
 | 
			
		||||
    <noscript>Please enable JavaScript to continue using this application.</noscript>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										59
									
								
								angular/src/manifest.webmanifest
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,59 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "BookStore",
 | 
			
		||||
  "short_name": "BookStore",
 | 
			
		||||
  "theme_color": "#1976d2",
 | 
			
		||||
  "background_color": "#fafafa",
 | 
			
		||||
  "display": "standalone",
 | 
			
		||||
  "scope": "./",
 | 
			
		||||
  "start_url": "./",
 | 
			
		||||
  "icons": [
 | 
			
		||||
    {
 | 
			
		||||
      "src": "assets/icons/icon-72x72.png",
 | 
			
		||||
      "sizes": "72x72",
 | 
			
		||||
      "type": "image/png",
 | 
			
		||||
      "purpose": "maskable any"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src": "assets/icons/icon-96x96.png",
 | 
			
		||||
      "sizes": "96x96",
 | 
			
		||||
      "type": "image/png",
 | 
			
		||||
      "purpose": "maskable any"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src": "assets/icons/icon-128x128.png",
 | 
			
		||||
      "sizes": "128x128",
 | 
			
		||||
      "type": "image/png",
 | 
			
		||||
      "purpose": "maskable any"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src": "assets/icons/icon-144x144.png",
 | 
			
		||||
      "sizes": "144x144",
 | 
			
		||||
      "type": "image/png",
 | 
			
		||||
      "purpose": "maskable any"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src": "assets/icons/icon-152x152.png",
 | 
			
		||||
      "sizes": "152x152",
 | 
			
		||||
      "type": "image/png",
 | 
			
		||||
      "purpose": "maskable any"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src": "assets/icons/icon-192x192.png",
 | 
			
		||||
      "sizes": "192x192",
 | 
			
		||||
      "type": "image/png",
 | 
			
		||||
      "purpose": "maskable any"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src": "assets/icons/icon-384x384.png",
 | 
			
		||||
      "sizes": "384x384",
 | 
			
		||||
      "type": "image/png",
 | 
			
		||||
      "purpose": "maskable any"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src": "assets/icons/icon-512x512.png",
 | 
			
		||||
      "sizes": "512x512",
 | 
			
		||||
      "type": "image/png",
 | 
			
		||||
      "purpose": "maskable any"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1003
									
								
								angular/yarn.lock
									
									
									
									
									
								
							
							
						
						@ -24,10 +24,10 @@ In the production environment, you need to use a production signing certificate.
 | 
			
		||||
This certificate is already generated by ABP CLI, so most of the time you don't need to generate it yourself. However, if you need to generate a certificate, you can use the following command:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
dotnet dev-certs https -v -ep openiddict.pfx -p 9d3dbfba-a400-4e7c-b7a2-779cd1b0c44f
 | 
			
		||||
dotnet dev-certs https -v -ep openiddict.pfx -p 70790fc6-826d-4901-86d8-1b6ae21c9efb
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
> `9d3dbfba-a400-4e7c-b7a2-779cd1b0c44f` is the password of the certificate, you can change it to any password you want.
 | 
			
		||||
> `70790fc6-826d-4901-86d8-1b6ae21c9efb` is the password of the certificate, you can change it to any password you want.
 | 
			
		||||
 | 
			
		||||
It is recommended to use **two** RSA certificates, distinct from the certificate(s) used for HTTPS: one for encryption, one for signing.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <Import Project="..\..\common.props" />
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,44 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.ComponentModel.DataAnnotations;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Volo.Abp.Application.Dtos;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Authors
 | 
			
		||||
{
 | 
			
		||||
    public class AuthorDto : EntityDto<Guid>
 | 
			
		||||
    {
 | 
			
		||||
        public string Name { get; set; }
 | 
			
		||||
 | 
			
		||||
        public DateTime BirthDate { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string ShortBio { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
    public class GetAuthorListDto : PagedAndSortedResultRequestDto
 | 
			
		||||
    {
 | 
			
		||||
        public string? Filter { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
    public class CreateAuthorDto
 | 
			
		||||
    {
 | 
			
		||||
        [Required]
 | 
			
		||||
        [StringLength(AuthorConsts.MaxNameLength)]
 | 
			
		||||
        public string Name { get; set; } = string.Empty;
 | 
			
		||||
 | 
			
		||||
        [Required]
 | 
			
		||||
        public DateTime BirthDate { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string? ShortBio { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class UpdateAuthorDto
 | 
			
		||||
    {
 | 
			
		||||
        [Required]
 | 
			
		||||
        [StringLength(AuthorConsts.MaxNameLength)]
 | 
			
		||||
        public string Name { get; set; } = string.Empty;
 | 
			
		||||
 | 
			
		||||
        [Required]
 | 
			
		||||
        public DateTime BirthDate { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string? ShortBio { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Application.Dtos;
 | 
			
		||||
using Volo.Abp.Application.Services;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Authors;
 | 
			
		||||
 | 
			
		||||
public interface IAuthorAppService : IApplicationService
 | 
			
		||||
{
 | 
			
		||||
    Task<AuthorDto> GetAsync(Guid id);
 | 
			
		||||
 | 
			
		||||
    Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorListDto input);
 | 
			
		||||
 | 
			
		||||
    Task<AuthorDto> CreateAsync(CreateAuthorDto input);
 | 
			
		||||
 | 
			
		||||
    Task UpdateAsync(Guid id, UpdateAuthorDto input);
 | 
			
		||||
 | 
			
		||||
    Task DeleteAsync(Guid id);
 | 
			
		||||
}
 | 
			
		||||
@ -1,25 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.ComponentModel.DataAnnotations;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Volo.Abp.Application.Dtos;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.BookIssued
 | 
			
		||||
{
 | 
			
		||||
    public class BookIssueDto : EntityDto<int>
 | 
			
		||||
    {
 | 
			
		||||
        [Required]
 | 
			
		||||
        public Guid bookId { get; set; }
 | 
			
		||||
        [Required]
 | 
			
		||||
        public int customerId { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class BookIssueListDto
 | 
			
		||||
    {
 | 
			
		||||
        public int bookIssueId { get; set; }
 | 
			
		||||
        public string bookName { get; set; }
 | 
			
		||||
        public string customerName { get; set; }
 | 
			
		||||
        public DateTime issueDate { get; set; }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,22 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Application.Dtos;
 | 
			
		||||
using Volo.Abp.Application.Services;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.BookIssued
 | 
			
		||||
{
 | 
			
		||||
    public interface IBookIssueAppService : IApplicationService
 | 
			
		||||
    {
 | 
			
		||||
        Task<BookIssueDto> GetAsync(int id);
 | 
			
		||||
 | 
			
		||||
        Task<PagedResultDto<BookIssueListDto>> GetListAsync();
 | 
			
		||||
 | 
			
		||||
        Task<BookIssueDto> CreateAsync(BookIssueDto input);
 | 
			
		||||
 | 
			
		||||
        Task UpdateAsync(int id, BookIssueDto input);
 | 
			
		||||
 | 
			
		||||
        Task DeleteAsync(int id);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Volo.Abp.Application.Dtos;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Books
 | 
			
		||||
{
 | 
			
		||||
    public class BookDto : AuditedEntityDto<Guid>
 | 
			
		||||
    {
 | 
			
		||||
        public string Name { get; set; }
 | 
			
		||||
 | 
			
		||||
        public BookType Type { get; set; }
 | 
			
		||||
 | 
			
		||||
        public DateTime PublishDate { get; set; }
 | 
			
		||||
 | 
			
		||||
        public float Price { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,24 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.ComponentModel.DataAnnotations;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Books
 | 
			
		||||
{
 | 
			
		||||
    public class CreateUpdateBookDto
 | 
			
		||||
    {
 | 
			
		||||
        [Required]
 | 
			
		||||
        [StringLength(128)]
 | 
			
		||||
        public string Name { get; set; } = string.Empty;
 | 
			
		||||
 | 
			
		||||
        [Required]
 | 
			
		||||
        public BookType Type { get; set; } = BookType.Undefined;
 | 
			
		||||
 | 
			
		||||
        [Required]
 | 
			
		||||
        [DataType(DataType.Date)]
 | 
			
		||||
        public DateTime PublishDate { get; set; } = DateTime.Now;
 | 
			
		||||
 | 
			
		||||
        [Required]
 | 
			
		||||
        public float Price { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Application.Dtos;
 | 
			
		||||
using Volo.Abp.Application.Services;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Books
 | 
			
		||||
{
 | 
			
		||||
    public interface IBookAppService :
 | 
			
		||||
    ICrudAppService< //Defines CRUD methods
 | 
			
		||||
        BookDto, //Used to show books
 | 
			
		||||
        Guid, //Primary key of the book entity
 | 
			
		||||
        PagedAndSortedResultRequestDto, //Used for paging/sorting
 | 
			
		||||
        CreateUpdateBookDto> //Used to create/update a book
 | 
			
		||||
    {
 | 
			
		||||
      Task<List<BookDto>> GetBookDropDown();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,20 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.ComponentModel.DataAnnotations;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Volo.Abp.Application.Dtos;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Customers
 | 
			
		||||
{
 | 
			
		||||
    public class CustomerDto : EntityDto<int>
 | 
			
		||||
    {
 | 
			
		||||
        [Required]
 | 
			
		||||
        public string firstName { get; set; }
 | 
			
		||||
        [Required]
 | 
			
		||||
        public string lastName { get; set; }
 | 
			
		||||
        [Required]
 | 
			
		||||
        public string phone { get; set; }
 | 
			
		||||
        [Required]
 | 
			
		||||
        public string address { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,24 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Application.Dtos;
 | 
			
		||||
using Volo.Abp.Application.Services;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Customers
 | 
			
		||||
{
 | 
			
		||||
    public interface ICustomerAppService : IApplicationService
 | 
			
		||||
    {
 | 
			
		||||
        Task<CustomerDto> GetAsync(int id);
 | 
			
		||||
 | 
			
		||||
        Task<PagedResultDto<CustomerDto>> GetListAsync();
 | 
			
		||||
 | 
			
		||||
        Task<CustomerDto> CreateAsync(CustomerDto input); 
 | 
			
		||||
 | 
			
		||||
        Task UpdateAsync(int id, CustomerDto input);
 | 
			
		||||
 | 
			
		||||
        Task DeleteAsync(int id);
 | 
			
		||||
        Task<List<CustomerDto>> GetcustomerDropDown();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -11,40 +11,6 @@ public class BookStorePermissionDefinitionProvider : PermissionDefinitionProvide
 | 
			
		||||
        var myGroup = context.AddGroup(BookStorePermissions.GroupName);
 | 
			
		||||
        //Define your own permissions here. Example:
 | 
			
		||||
        //myGroup.AddPermission(BookStorePermissions.MyPermission1, L("Permission:MyPermission1"));
 | 
			
		||||
 | 
			
		||||
        var booksPermission = myGroup.AddPermission(BookStorePermissions.Books.Default, L("Permission:Books"));
 | 
			
		||||
        booksPermission.AddChild(BookStorePermissions.Books.Create, L("Permission:Books.Create"));
 | 
			
		||||
        booksPermission.AddChild(BookStorePermissions.Books.Edit, L("Permission:Books.Edit"));
 | 
			
		||||
        booksPermission.AddChild(BookStorePermissions.Books.Delete, L("Permission:Books.Delete"));
 | 
			
		||||
 | 
			
		||||
        var authorsPermission = myGroup.AddPermission(
 | 
			
		||||
    BookStorePermissions.Authors.Default, L("Permission:Authors"));
 | 
			
		||||
        authorsPermission.AddChild(
 | 
			
		||||
            BookStorePermissions.Authors.Create, L("Permission:Authors.Create"));
 | 
			
		||||
        authorsPermission.AddChild(
 | 
			
		||||
            BookStorePermissions.Authors.Edit, L("Permission:Authors.Edit"));
 | 
			
		||||
        authorsPermission.AddChild(
 | 
			
		||||
            BookStorePermissions.Authors.Delete, L("Permission:Authors.Delete"));
 | 
			
		||||
 | 
			
		||||
        var customersPermission = myGroup.AddPermission(
 | 
			
		||||
    BookStorePermissions.Customers.Default, L("Permission:Customers"));
 | 
			
		||||
        customersPermission.AddChild(
 | 
			
		||||
            BookStorePermissions.Customers.Create, L("Permission:Customers.Create"));
 | 
			
		||||
        customersPermission.AddChild(
 | 
			
		||||
            BookStorePermissions.Customers.Edit, L("Permission:Customers.Edit"));
 | 
			
		||||
        customersPermission.AddChild(
 | 
			
		||||
            BookStorePermissions.Customers.Delete, L("Permission:Customers.Delete"));
 | 
			
		||||
 | 
			
		||||
        var bookissuedPermission = myGroup.AddPermission(
 | 
			
		||||
    BookStorePermissions.BookIssued.Default, L("Permission:BookIssued"));
 | 
			
		||||
        bookissuedPermission.AddChild(
 | 
			
		||||
            BookStorePermissions.BookIssued.Create, L("Permission:BookIssued.Create"));
 | 
			
		||||
        bookissuedPermission.AddChild(
 | 
			
		||||
            BookStorePermissions.BookIssued.Edit, L("Permission:BookIssued.Edit"));
 | 
			
		||||
        bookissuedPermission.AddChild(
 | 
			
		||||
            BookStorePermissions.BookIssued.Delete, L("Permission:BookIssued.Delete"));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static LocalizableString L(string name)
 | 
			
		||||
 | 
			
		||||
@ -4,35 +4,6 @@ public static class BookStorePermissions
 | 
			
		||||
{
 | 
			
		||||
    public const string GroupName = "BookStore";
 | 
			
		||||
 | 
			
		||||
    public static class Books
 | 
			
		||||
    {
 | 
			
		||||
        public const string Default = GroupName + ".Books";
 | 
			
		||||
        public const string Create = Default + ".Create";
 | 
			
		||||
        public const string Edit = Default + ".Edit";
 | 
			
		||||
        public const string Delete = Default + ".Delete";
 | 
			
		||||
    }
 | 
			
		||||
    public static class Authors
 | 
			
		||||
    {
 | 
			
		||||
        public const string Default = GroupName + ".Authors";
 | 
			
		||||
        public const string Create = Default + ".Create";
 | 
			
		||||
        public const string Edit = Default + ".Edit";
 | 
			
		||||
        public const string Delete = Default + ".Delete";
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static class Customers
 | 
			
		||||
    {
 | 
			
		||||
        public const string Default = GroupName + ".Customers";
 | 
			
		||||
        public const string Create = Default + ".Create";
 | 
			
		||||
        public const string Edit = Default + ".Edit";
 | 
			
		||||
        public const string Delete = Default + ".Delete";
 | 
			
		||||
    }
 | 
			
		||||
    public static class BookIssued
 | 
			
		||||
    {
 | 
			
		||||
        public const string Default = GroupName + ".BookIssued";
 | 
			
		||||
        public const string Create = Default + ".Create";
 | 
			
		||||
        public const string Edit = Default + ".Edit";
 | 
			
		||||
        public const string Delete = Default + ".Delete";
 | 
			
		||||
    }
 | 
			
		||||
    //Add your own permission names. Example:
 | 
			
		||||
    //public const string MyPermission1 = GroupName + ".MyPermission1";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <Import Project="..\..\common.props" />
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,95 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Acme.BookStore.Permissions;
 | 
			
		||||
using Microsoft.AspNetCore.Authorization;
 | 
			
		||||
using Volo.Abp.Application.Dtos;
 | 
			
		||||
using Volo.Abp.Domain.Repositories;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Authors
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    [Authorize(BookStorePermissions.Authors.Default)]
 | 
			
		||||
    public class AuthorAppService : BookStoreAppService, IAuthorAppService
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IAuthorRepository _authorRepository;
 | 
			
		||||
        private readonly AuthorManager _authorManager;
 | 
			
		||||
 | 
			
		||||
        public AuthorAppService(
 | 
			
		||||
            IAuthorRepository authorRepository,
 | 
			
		||||
            AuthorManager authorManager)
 | 
			
		||||
        {
 | 
			
		||||
            _authorRepository = authorRepository;
 | 
			
		||||
            _authorManager = authorManager;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<AuthorDto> GetAsync(Guid id)
 | 
			
		||||
        {
 | 
			
		||||
            var author = await _authorRepository.GetAsync(id);
 | 
			
		||||
            return ObjectMapper.Map<Author, AuthorDto>(author);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorListDto input)
 | 
			
		||||
        {
 | 
			
		||||
            if (input.Sorting.IsNullOrWhiteSpace())
 | 
			
		||||
            {
 | 
			
		||||
                input.Sorting = nameof(Author.Name);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var authors = await _authorRepository.GetListAsync(
 | 
			
		||||
                input.SkipCount,
 | 
			
		||||
                input.MaxResultCount,
 | 
			
		||||
                input.Sorting,
 | 
			
		||||
                input.Filter
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            var totalCount = input.Filter == null
 | 
			
		||||
                ? await _authorRepository.CountAsync()
 | 
			
		||||
                : await _authorRepository.CountAsync(
 | 
			
		||||
                    author => author.Name.Contains(input.Filter));
 | 
			
		||||
 | 
			
		||||
            return new PagedResultDto<AuthorDto>(
 | 
			
		||||
                totalCount,
 | 
			
		||||
                ObjectMapper.Map<List<Author>, List<AuthorDto>>(authors)
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Authorize(BookStorePermissions.Authors.Create)]
 | 
			
		||||
        public async Task<AuthorDto> CreateAsync(CreateAuthorDto input)
 | 
			
		||||
        {
 | 
			
		||||
            var author = await _authorManager.CreateAsync(
 | 
			
		||||
                input.Name,
 | 
			
		||||
                input.BirthDate,
 | 
			
		||||
                input.ShortBio
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            await _authorRepository.InsertAsync(author);
 | 
			
		||||
 | 
			
		||||
            return ObjectMapper.Map<Author, AuthorDto>(author);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Authorize(BookStorePermissions.Authors.Edit)]
 | 
			
		||||
        public async Task UpdateAsync(Guid id, UpdateAuthorDto input)
 | 
			
		||||
        {
 | 
			
		||||
            var author = await _authorRepository.GetAsync(id);
 | 
			
		||||
 | 
			
		||||
            if (author.Name != input.Name)
 | 
			
		||||
            {
 | 
			
		||||
                await _authorManager.ChangeNameAsync(author, input.Name);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            author.BirthDate = input.BirthDate;
 | 
			
		||||
            author.ShortBio = input.ShortBio;
 | 
			
		||||
 | 
			
		||||
            await _authorRepository.UpdateAsync(author);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        [Authorize(BookStorePermissions.Authors.Delete)]
 | 
			
		||||
        public async Task DeleteAsync(Guid id)
 | 
			
		||||
        {
 | 
			
		||||
            await _authorRepository.DeleteAsync(id);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,73 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Acme.BookStore.BookIssued;
 | 
			
		||||
using Volo.Abp.Application.Dtos;
 | 
			
		||||
using Acme.BookStore.Permissions;
 | 
			
		||||
using Microsoft.AspNetCore.Authorization;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.BookIssued
 | 
			
		||||
{
 | 
			
		||||
    public class BookIssueAppService : BookStoreAppService, IBookIssueAppService
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IBookIssueRepository _bookIssueRepository;
 | 
			
		||||
        private readonly BookIssueManager _bookIssueManager;
 | 
			
		||||
 | 
			
		||||
        public BookIssueAppService(
 | 
			
		||||
            IBookIssueRepository bookIssueRepository,
 | 
			
		||||
            BookIssueManager bookIssueManager)
 | 
			
		||||
        {
 | 
			
		||||
            _bookIssueRepository = bookIssueRepository;
 | 
			
		||||
            _bookIssueManager = bookIssueManager;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<BookIssueDto> GetAsync(int id)
 | 
			
		||||
        {
 | 
			
		||||
            var cus = await _bookIssueRepository.GetAsync(id);
 | 
			
		||||
            return ObjectMapper.Map<BookIssue, BookIssueDto>(cus);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<PagedResultDto<BookIssueListDto>> GetListAsync()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            var cus = await _bookIssueRepository.BookIssueList();
 | 
			
		||||
 | 
			
		||||
            return new PagedResultDto<BookIssueListDto>(
 | 
			
		||||
                cus.Count(),
 | 
			
		||||
                ObjectMapper.Map<List<BookIssueList>, List<BookIssueListDto>>(cus)
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
         
 | 
			
		||||
 | 
			
		||||
         [Authorize(BookStorePermissions.BookIssued.Create)]
 | 
			
		||||
 | 
			
		||||
        public async Task<BookIssueDto> CreateAsync(BookIssueDto input)
 | 
			
		||||
        {
 | 
			
		||||
            var cus = ObjectMapper.Map<BookIssueDto, BookIssue>(input);
 | 
			
		||||
            var cust = await _bookIssueManager.CreateAsync(cus);
 | 
			
		||||
 | 
			
		||||
            var res =  await _bookIssueRepository.InsertAsync(cust);
 | 
			
		||||
 | 
			
		||||
            return ObjectMapper.Map<BookIssue, BookIssueDto>(cust);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Authorize(BookStorePermissions.BookIssued.Edit)]
 | 
			
		||||
        public async Task UpdateAsync(int id, BookIssueDto input)
 | 
			
		||||
        {
 | 
			
		||||
            var cus = await _bookIssueRepository.GetAsync(id);
 | 
			
		||||
             
 | 
			
		||||
            await _bookIssueRepository.UpdateAsync(cus);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        [Authorize(BookStorePermissions.BookIssued.Delete)]
 | 
			
		||||
        public async Task DeleteAsync(int id)
 | 
			
		||||
        {
 | 
			
		||||
            await _bookIssueRepository.DeleteAsync(id);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,23 +1,11 @@
 | 
			
		||||
using AutoMapper;
 | 
			
		||||
using Acme.BookStore.Books;
 | 
			
		||||
using Acme.BookStore.Authors;
 | 
			
		||||
using Acme.BookStore.Customers;
 | 
			
		||||
using Acme.BookStore.BookIssued;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore;
 | 
			
		||||
 | 
			
		||||
public class BookStoreApplicationAutoMapperProfile : Profile
 | 
			
		||||
{
 | 
			
		||||
    public BookStoreApplicationAutoMapperProfile()
 | 
			
		||||
    {
 | 
			
		||||
        CreateMap<Book, BookDto>();
 | 
			
		||||
        //CreateMap<List<Book>, List<BookDto>>().ReverseMap();
 | 
			
		||||
        CreateMap<CreateUpdateBookDto, Book>();
 | 
			
		||||
        CreateMap<Author, AuthorDto>();
 | 
			
		||||
        CreateMap<Customer, CustomerDto>().ReverseMap();
 | 
			
		||||
      //  CreateMap<List<Customer>, List<CustomerDto>>().ReverseMap();
 | 
			
		||||
        CreateMap<BookIssue, BookIssueDto>().ReverseMap();
 | 
			
		||||
        CreateMap<BookIssueList, BookIssueListDto>().ReverseMap();
 | 
			
		||||
 | 
			
		||||
        /* You can configure your AutoMapper mapping configuration here.
 | 
			
		||||
         * Alternatively, you can split your mapping configurations
 | 
			
		||||
         * into multiple profile classes for a better organization. */
 | 
			
		||||
 | 
			
		||||
@ -1,43 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Application.Dtos;
 | 
			
		||||
using Volo.Abp.Application.Services;
 | 
			
		||||
using Volo.Abp.Domain.Repositories;
 | 
			
		||||
using Acme.BookStore.Permissions; 
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Books
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    public class BookAppService :
 | 
			
		||||
        CrudAppService<
 | 
			
		||||
            Book, //The Book entity
 | 
			
		||||
            BookDto, //Used to show books
 | 
			
		||||
            Guid, //Primary key of the book entity
 | 
			
		||||
            PagedAndSortedResultRequestDto, //Used for paging/sorting
 | 
			
		||||
            CreateUpdateBookDto>, //Used to create/update a book
 | 
			
		||||
        IBookAppService //implement the IBookAppService
 | 
			
		||||
    {
 | 
			
		||||
         private readonly IRepository<Book, Guid> _bookRepository;
 | 
			
		||||
        public BookAppService(IRepository<Book, Guid> repository)
 | 
			
		||||
            : base(repository)
 | 
			
		||||
        {
 | 
			
		||||
           _bookRepository = repository;
 | 
			
		||||
            GetPolicyName = BookStorePermissions.Books.Default;
 | 
			
		||||
            GetListPolicyName = BookStorePermissions.Books.Default;
 | 
			
		||||
            CreatePolicyName = BookStorePermissions.Books.Create;
 | 
			
		||||
            UpdatePolicyName = BookStorePermissions.Books.Edit;
 | 
			
		||||
            DeletePolicyName = BookStorePermissions.Books.Delete;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<List<BookDto>> GetBookDropDown()
 | 
			
		||||
        {
 | 
			
		||||
            var cus = await _bookRepository.GetListAsync();
 | 
			
		||||
            cus = cus == null ? new List<Book>() : cus;
 | 
			
		||||
            return ObjectMapper.Map<List<Book>, List<BookDto>>(cus);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,86 +0,0 @@
 | 
			
		||||
using Acme.BookStore.Customers;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Application.Dtos;
 | 
			
		||||
using Volo.Abp.Application.Services;
 | 
			
		||||
using Volo.Abp.ObjectMapping;
 | 
			
		||||
using Acme.BookStore.Permissions;
 | 
			
		||||
using Microsoft.AspNetCore.Authorization;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Customers
 | 
			
		||||
{
 | 
			
		||||
    public class CustomerAppService: BookStoreAppService, ICustomerAppService
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ICustomerRepository _customerRepository;
 | 
			
		||||
        private readonly CustomerManager _customerManager;
 | 
			
		||||
 | 
			
		||||
        public CustomerAppService(
 | 
			
		||||
            ICustomerRepository customerRepository,
 | 
			
		||||
            CustomerManager customerManager)
 | 
			
		||||
        {
 | 
			
		||||
            _customerRepository = customerRepository;
 | 
			
		||||
            _customerManager = customerManager;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<CustomerDto> GetAsync(int id)
 | 
			
		||||
        {
 | 
			
		||||
            var cus = await _customerRepository.GetAsync(id);
 | 
			
		||||
            return ObjectMapper.Map<Customer, CustomerDto>(cus);
 | 
			
		||||
        }
 | 
			
		||||
        public async Task<List<CustomerDto>> GetcustomerDropDown()
 | 
			
		||||
        {
 | 
			
		||||
            var cus = await _customerRepository.GetListAsync();
 | 
			
		||||
            cus = cus == null ? new List<Customer>() : cus;
 | 
			
		||||
            return ObjectMapper.Map<List<Customer>, List<CustomerDto>>(cus);
 | 
			
		||||
        }
 | 
			
		||||
         
 | 
			
		||||
        public async Task<PagedResultDto<CustomerDto>> GetListAsync()
 | 
			
		||||
        { 
 | 
			
		||||
 | 
			
		||||
            var cus = await _customerRepository.GetListAsync();
 | 
			
		||||
             
 | 
			
		||||
            return new PagedResultDto<CustomerDto>(
 | 
			
		||||
                cus.Count(),
 | 
			
		||||
                ObjectMapper.Map<List<Customer>, List<CustomerDto>>(cus)
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        [Authorize(BookStorePermissions.Customers.Create)]
 | 
			
		||||
 | 
			
		||||
        public async Task<CustomerDto> CreateAsync(CustomerDto input)
 | 
			
		||||
        {
 | 
			
		||||
           var cus = ObjectMapper.Map<CustomerDto,Customer>(input);
 | 
			
		||||
            var cust = await _customerManager.CreateAsync(cus); 
 | 
			
		||||
 | 
			
		||||
            await _customerRepository.InsertAsync(cust);
 | 
			
		||||
 | 
			
		||||
            return ObjectMapper.Map<Customer, CustomerDto>(cust);
 | 
			
		||||
        }
 | 
			
		||||
         
 | 
			
		||||
        [Authorize(BookStorePermissions.Customers.Edit)]
 | 
			
		||||
 | 
			
		||||
        public async Task UpdateAsync(int id, CustomerDto input)
 | 
			
		||||
        {
 | 
			
		||||
            var cus = await _customerRepository.GetAsync(id);
 | 
			
		||||
 | 
			
		||||
            if (cus.phone == input.phone)
 | 
			
		||||
            {
 | 
			
		||||
                await _customerManager.ChangeNameAsync(cus, input.firstName,input.lastName);
 | 
			
		||||
            }
 | 
			
		||||
             
 | 
			
		||||
            await _customerRepository.UpdateAsync(cus);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
         
 | 
			
		||||
        [Authorize(BookStorePermissions.Customers.Delete)]
 | 
			
		||||
 | 
			
		||||
        public async Task DeleteAsync(int id)
 | 
			
		||||
        {
 | 
			
		||||
            await _customerRepository.DeleteAsync(id);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -10,7 +10,7 @@
 | 
			
		||||
      },
 | 
			
		||||
      "BookStore_Swagger": {
 | 
			
		||||
        "ClientId": "BookStore_Swagger",
 | 
			
		||||
        "RootUrl": "https://localhost:44356"
 | 
			
		||||
        "RootUrl": "https://localhost:44362"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <Import Project="..\..\common.props" />
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,12 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Authors
 | 
			
		||||
{
 | 
			
		||||
    public static class AuthorConsts
 | 
			
		||||
    {
 | 
			
		||||
        public const int MaxNameLength = 64;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -2,9 +2,5 @@
 | 
			
		||||
 | 
			
		||||
public static class BookStoreDomainErrorCodes
 | 
			
		||||
{
 | 
			
		||||
    public const string AuthorAlreadyExists = "BookStore:00001";
 | 
			
		||||
    public const string CustomerPhoneAlreadyExists = "BookStore:00002";
 | 
			
		||||
    public const string BookIssuedAlready = "BookStore:00003";
 | 
			
		||||
 | 
			
		||||
    /* You can add your business exception error codes here, as constants */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Books
 | 
			
		||||
{
 | 
			
		||||
    public enum BookType
 | 
			
		||||
    {
 | 
			
		||||
        Undefined,
 | 
			
		||||
        Adventure,
 | 
			
		||||
        Biography,
 | 
			
		||||
        Dystopia,
 | 
			
		||||
        Fantastic,
 | 
			
		||||
        Horror,
 | 
			
		||||
        Science,
 | 
			
		||||
        ScienceFiction,
 | 
			
		||||
        Poetry
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Customers
 | 
			
		||||
{
 | 
			
		||||
    public class CustomerConsts
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        public const int MaxNameLength = 100;
 | 
			
		||||
        public const int MaxPhoneLength = 14;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -3,51 +3,6 @@
 | 
			
		||||
  "texts": {
 | 
			
		||||
    "Menu:Home": "Home",
 | 
			
		||||
    "Welcome": "Welcome",
 | 
			
		||||
    "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io.",
 | 
			
		||||
    "Menu:BookStore": "Book Store",
 | 
			
		||||
    "Menu:Books": "Books",
 | 
			
		||||
    "Actions": "Actions",
 | 
			
		||||
    "Close": "Close",
 | 
			
		||||
    "Delete": "Delete",
 | 
			
		||||
    "Edit": "Edit",
 | 
			
		||||
    "PublishDate": "Publish date",
 | 
			
		||||
    "NewBook": "New book",
 | 
			
		||||
    "Name": "Name",
 | 
			
		||||
    "Type": "Type",
 | 
			
		||||
    "Price": "Price",
 | 
			
		||||
    "CreationTime": "Creation time",
 | 
			
		||||
    "AreYouSure": "Are you sure?",
 | 
			
		||||
    "AreYouSureToDelete": "Are you sure you want to delete this item?",
 | 
			
		||||
    "Enum:BookType.0": "Undefined",
 | 
			
		||||
    "Enum:BookType.1": "Adventure",
 | 
			
		||||
    "Enum:BookType.2": "Biography",
 | 
			
		||||
    "Enum:BookType.3": "Dystopia",
 | 
			
		||||
    "Enum:BookType.4": "Fantastic",
 | 
			
		||||
    "Enum:BookType.5": "Horror",
 | 
			
		||||
    "Enum:BookType.6": "Science",
 | 
			
		||||
    "Enum:BookType.7": "Science fiction",
 | 
			
		||||
    "Enum:BookType.8": "Poetry",
 | 
			
		||||
    "Permission:BookStore": "Book Store",
 | 
			
		||||
    "Permission:Books": "Book Management",
 | 
			
		||||
    "Permission:Books.Create": "Creating new books",
 | 
			
		||||
    "Permission:Books.Edit": "Editing the books",
 | 
			
		||||
    "Permission:Books.Delete": "Deleting the books",
 | 
			
		||||
    "BookStore:00001": "There is already an author with the same name: {name}",
 | 
			
		||||
    "BookStore:00002": "There is already an customer with the same phone: {phone}",
 | 
			
		||||
    "BookStore:00003": "{book} Book already issued to customer: {customer}",
 | 
			
		||||
    "Permission:Authors": "Author Management",
 | 
			
		||||
    "Permission:Authors.Create": "Creating new authors",
 | 
			
		||||
    "Permission:Authors.Edit": "Editing the authors",
 | 
			
		||||
    "Permission:Authors.Delete": "Deleting the authors",
 | 
			
		||||
    "Permission:Customers": "Customer Management",
 | 
			
		||||
    "Permission:Customers.Create": "Creating new Customer",
 | 
			
		||||
    "Permission:Customers.Edit": "Editing the Customer",
 | 
			
		||||
    "Permission:Customers.Delete": "Deleting the Customer",
 | 
			
		||||
    "Permission:BookIssued": "Book Issued Management",
 | 
			
		||||
    "Permission:BookIssued.Create": "Creating new Issued Book",
 | 
			
		||||
    "Permission:BookIssued.Edit": "Editing the Issued Book",
 | 
			
		||||
    "Permission:BookIssued.Delete": "Deleting the Issued Book"
 | 
			
		||||
    "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io."
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <Import Project="..\..\common.props" />
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,48 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp;
 | 
			
		||||
using Volo.Abp.Domain.Entities.Auditing;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Authors
 | 
			
		||||
{
 | 
			
		||||
    public class Author : FullAuditedAggregateRoot<Guid>
 | 
			
		||||
    {
 | 
			
		||||
        public string Name { get; private set; }
 | 
			
		||||
        public DateTime BirthDate { get; set; }
 | 
			
		||||
        public string ShortBio { get; set; }
 | 
			
		||||
 | 
			
		||||
        private Author()
 | 
			
		||||
        {
 | 
			
		||||
            /* This constructor is for deserialization / ORM purpose */
 | 
			
		||||
        }
 | 
			
		||||
        internal Author(
 | 
			
		||||
       Guid id,
 | 
			
		||||
       string name,
 | 
			
		||||
       DateTime birthDate,
 | 
			
		||||
       string? shortBio = null)
 | 
			
		||||
       : base(id)
 | 
			
		||||
        {
 | 
			
		||||
            SetName(name);
 | 
			
		||||
            BirthDate = birthDate;
 | 
			
		||||
            ShortBio = shortBio;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal Author ChangeName(string name)
 | 
			
		||||
        {
 | 
			
		||||
            SetName(name);
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SetName(string name)
 | 
			
		||||
        {
 | 
			
		||||
            Name = Check.NotNullOrWhiteSpace(
 | 
			
		||||
                name,
 | 
			
		||||
                nameof(name),
 | 
			
		||||
                maxLength: AuthorConsts.MaxNameLength
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Authors
 | 
			
		||||
{
 | 
			
		||||
    public class AuthorAlreadyExistsException : BusinessException
 | 
			
		||||
    {
 | 
			
		||||
        public AuthorAlreadyExistsException(string name)
 | 
			
		||||
            : base(BookStoreDomainErrorCodes.AuthorAlreadyExists)
 | 
			
		||||
        {
 | 
			
		||||
            WithData("name", name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,57 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp;
 | 
			
		||||
using Volo.Abp.Domain.Services;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Authors
 | 
			
		||||
{
 | 
			
		||||
    public class AuthorManager : DomainService
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IAuthorRepository _authorRepository;
 | 
			
		||||
 | 
			
		||||
        public AuthorManager(IAuthorRepository authorRepository)
 | 
			
		||||
        {
 | 
			
		||||
            _authorRepository = authorRepository;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<Author> CreateAsync(
 | 
			
		||||
            string name,
 | 
			
		||||
            DateTime birthDate,
 | 
			
		||||
            string? shortBio = null)
 | 
			
		||||
        {
 | 
			
		||||
            Check.NotNullOrWhiteSpace(name, nameof(name));
 | 
			
		||||
 | 
			
		||||
            var existingAuthor = await _authorRepository.FindByNameAsync(name);
 | 
			
		||||
            if (existingAuthor != null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new AuthorAlreadyExistsException(name);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new Author(
 | 
			
		||||
                GuidGenerator.Create(),
 | 
			
		||||
                name,
 | 
			
		||||
                birthDate,
 | 
			
		||||
                shortBio
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task ChangeNameAsync(
 | 
			
		||||
            Author author,
 | 
			
		||||
            string newName)
 | 
			
		||||
        {
 | 
			
		||||
            Check.NotNull(author, nameof(author));
 | 
			
		||||
            Check.NotNullOrWhiteSpace(newName, nameof(newName));
 | 
			
		||||
 | 
			
		||||
            var existingAuthor = await _authorRepository.FindByNameAsync(newName);
 | 
			
		||||
            if (existingAuthor != null && existingAuthor.Id != author.Id)
 | 
			
		||||
            {
 | 
			
		||||
                throw new AuthorAlreadyExistsException(newName);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            author.ChangeName(newName);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Domain.Repositories;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Authors
 | 
			
		||||
{
 | 
			
		||||
    public interface IAuthorRepository : IRepository<Author, Guid>
 | 
			
		||||
    {
 | 
			
		||||
        Task<Author> FindByNameAsync(string name);
 | 
			
		||||
 | 
			
		||||
        Task<List<Author>> GetListAsync(
 | 
			
		||||
            int skipCount,
 | 
			
		||||
            int maxResultCount,
 | 
			
		||||
            string sorting,
 | 
			
		||||
            string filter = null
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Domain.Entities.Auditing;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.BookIssued
 | 
			
		||||
{
 | 
			
		||||
    public class BookIssue : FullAuditedAggregateRoot<int>
 | 
			
		||||
    {
 | 
			
		||||
        public Guid bookId { get; set; }
 | 
			
		||||
        public int customerId { get; set; }
 | 
			
		||||
        private BookIssue()
 | 
			
		||||
        {
 | 
			
		||||
            /* This constructor is for deserialization / ORM purpose */
 | 
			
		||||
        }
 | 
			
		||||
        internal BookIssue(int id, Guid bookId, int customerId) : base(id)
 | 
			
		||||
        {
 | 
			
		||||
            this.bookId = bookId;
 | 
			
		||||
            this.customerId = customerId; 
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class BookIssueList
 | 
			
		||||
    {
 | 
			
		||||
        public int bookIssueId { get; set; }
 | 
			
		||||
        public string bookName { get; set; }
 | 
			
		||||
        public string customerName { get; set; } 
 | 
			
		||||
        public DateTime issueDate { get; set; }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.BookIssued
 | 
			
		||||
{
 | 
			
		||||
    public class BookIssueErrorException : BusinessException
 | 
			
		||||
    {
 | 
			
		||||
        public BookIssueErrorException(string customerName, string bookName)
 | 
			
		||||
         : base(BookStoreDomainErrorCodes.BookIssuedAlready)
 | 
			
		||||
        {
 | 
			
		||||
            WithData("customer", customerName);
 | 
			
		||||
            WithData("book", bookName);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,36 +0,0 @@
 | 
			
		||||
using Acme.BookStore.Customers;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp;
 | 
			
		||||
using Volo.Abp.Domain.Services;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.BookIssued
 | 
			
		||||
{
 | 
			
		||||
    public class BookIssueManager : DomainService
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IBookIssueRepository _bookIssueRepository;
 | 
			
		||||
        public BookIssueManager(IBookIssueRepository bookIssueRepository)
 | 
			
		||||
        {
 | 
			
		||||
            _bookIssueRepository = bookIssueRepository;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<BookIssue> CreateAsync(
 | 
			
		||||
         BookIssue bookissue)
 | 
			
		||||
        { 
 | 
			
		||||
            var existingBookIssue = await _bookIssueRepository.FindBookIssueCustomer(bookissue.customerId,bookissue.bookId);
 | 
			
		||||
            if (existingBookIssue != null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new BookIssueErrorException(existingBookIssue.customerName, existingBookIssue.bookName);
 | 
			
		||||
            }
 | 
			
		||||
            return new BookIssue(
 | 
			
		||||
               await _bookIssueRepository.NewBookIssueId(),
 | 
			
		||||
                bookissue.bookId,
 | 
			
		||||
                bookissue.customerId
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,17 +0,0 @@
 | 
			
		||||
using Acme.BookStore.Customers;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Domain.Repositories;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.BookIssued
 | 
			
		||||
{
 | 
			
		||||
    public interface IBookIssueRepository : IRepository<BookIssue, int>
 | 
			
		||||
    {
 | 
			
		||||
        Task<BookIssueList> FindBookIssueCustomer(int customerId, Guid bookId);
 | 
			
		||||
        Task<int> NewBookIssueId();
 | 
			
		||||
        Task<List<BookIssueList>> BookIssueList();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,100 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks; 
 | 
			
		||||
using Acme.BookStore.Books;
 | 
			
		||||
using Volo.Abp.Data;
 | 
			
		||||
using Volo.Abp.DependencyInjection;
 | 
			
		||||
using Volo.Abp.Domain.Repositories;
 | 
			
		||||
 | 
			
		||||
using Acme.BookStore.Authors;
 | 
			
		||||
using Acme.BookStore.Customers;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore
 | 
			
		||||
{
 | 
			
		||||
    public class BookStoreDataSeederContributor
 | 
			
		||||
    : IDataSeedContributor, ITransientDependency
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IRepository<Book, Guid> _bookRepository;
 | 
			
		||||
        private readonly IAuthorRepository _authorRepository;
 | 
			
		||||
        private readonly ICustomerRepository _customerRepository;
 | 
			
		||||
        private readonly AuthorManager _authorManager;
 | 
			
		||||
        private readonly CustomerManager _customerManager;
 | 
			
		||||
 | 
			
		||||
        public BookStoreDataSeederContributor(IRepository<Book, Guid> bookRepository,
 | 
			
		||||
            IAuthorRepository authorRepository, 
 | 
			
		||||
            AuthorManager authorManager,
 | 
			
		||||
            ICustomerRepository customerRepository,
 | 
			
		||||
            CustomerManager customerManager
 | 
			
		||||
            )
 | 
			
		||||
        {
 | 
			
		||||
            _bookRepository = bookRepository;
 | 
			
		||||
 | 
			
		||||
            _authorRepository = authorRepository;
 | 
			
		||||
            _authorManager = authorManager;
 | 
			
		||||
 | 
			
		||||
            _customerRepository = customerRepository;
 | 
			
		||||
            _customerManager = customerManager;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task SeedAsync(DataSeedContext context)
 | 
			
		||||
        {
 | 
			
		||||
            if (await _bookRepository.GetCountAsync() <= 0)
 | 
			
		||||
            {
 | 
			
		||||
                await _bookRepository.InsertAsync(
 | 
			
		||||
                    new Book
 | 
			
		||||
                    {
 | 
			
		||||
                        Name = "1984",
 | 
			
		||||
                        Type = BookType.Dystopia,
 | 
			
		||||
                        PublishDate = new DateTime(1949, 6, 8),
 | 
			
		||||
                        Price = 19.84f
 | 
			
		||||
                    },
 | 
			
		||||
                    autoSave: true
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                await _bookRepository.InsertAsync(
 | 
			
		||||
                    new Book
 | 
			
		||||
                    {
 | 
			
		||||
                        Name = "The Hitchhiker's Guide to the Galaxy",
 | 
			
		||||
                        Type = BookType.ScienceFiction,
 | 
			
		||||
                        PublishDate = new DateTime(1995, 9, 27),
 | 
			
		||||
                        Price = 42.0f
 | 
			
		||||
                    },
 | 
			
		||||
                    autoSave: true
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            if (await _authorRepository.GetCountAsync() <= 0)
 | 
			
		||||
            {
 | 
			
		||||
                await _authorRepository.InsertAsync(
 | 
			
		||||
                await _authorManager.CreateAsync(
 | 
			
		||||
                        "George Orwell",
 | 
			
		||||
                        new DateTime(1903, 06, 25),
 | 
			
		||||
                        "Orwell produced literary criticism and poetry, fiction and polemical journalism; and is best known for the allegorical novella Animal Farm (1945) and the dystopian novel Nineteen Eighty-Four (1949)."
 | 
			
		||||
                    )
 | 
			
		||||
                );
 | 
			
		||||
                await _authorRepository.InsertAsync(
 | 
			
		||||
                await _authorManager.CreateAsync(
 | 
			
		||||
                        "Douglas Adams",
 | 
			
		||||
                        new DateTime(1952, 03, 11),
 | 
			
		||||
                        "Douglas Adams was an English author, screenwriter, essayist, humorist, satirist and dramatist. Adams was an advocate for environmentalism and conservation, a lover of fast cars, technological innovation and the Apple Macintosh, and a self-proclaimed 'radical atheist'."
 | 
			
		||||
                    )
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (await _customerRepository.GetCountAsync() <= 0)
 | 
			
		||||
            {
 | 
			
		||||
                Customer customer = new Customer(1, "soumen", "pal", "9091184026", "haripal");
 | 
			
		||||
 | 
			
		||||
                await _customerRepository.InsertAsync(
 | 
			
		||||
                await _customerManager.CreateAsync(customer)
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,20 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Domain.Entities.Auditing;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Books
 | 
			
		||||
{
 | 
			
		||||
    public class Book : AuditedAggregateRoot<Guid>
 | 
			
		||||
    {
 | 
			
		||||
        public string Name { get; set; }
 | 
			
		||||
 | 
			
		||||
        public BookType Type { get; set; }
 | 
			
		||||
 | 
			
		||||
        public DateTime PublishDate { get; set; }
 | 
			
		||||
 | 
			
		||||
        public float Price { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,60 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp;
 | 
			
		||||
using Volo.Abp.Domain.Entities.Auditing;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Customers
 | 
			
		||||
{
 | 
			
		||||
    public class Customer : FullAuditedAggregateRoot<int>
 | 
			
		||||
    {
 | 
			
		||||
        public string firstName { get; set; }
 | 
			
		||||
        public string lastName { get; set; } 
 | 
			
		||||
        public string phone { get; set; }
 | 
			
		||||
        public string address { get; set; }
 | 
			
		||||
        private Customer()
 | 
			
		||||
        {
 | 
			
		||||
            /* This constructor is for deserialization / ORM purpose */
 | 
			
		||||
        }
 | 
			
		||||
        internal Customer(int id, string firstName, string lastName, string phone, string address) : base(id)
 | 
			
		||||
        {
 | 
			
		||||
            this.firstName = firstName;
 | 
			
		||||
            this.lastName = lastName;
 | 
			
		||||
            this.phone = phone;
 | 
			
		||||
            this.address = address;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal Customer ChangeFirstName(string firstname)
 | 
			
		||||
        {
 | 
			
		||||
            SetFirstName(firstname);
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SetFirstName(string firstName)
 | 
			
		||||
        {
 | 
			
		||||
            firstName = Check.NotNullOrWhiteSpace(
 | 
			
		||||
                firstName,
 | 
			
		||||
                nameof(firstName),
 | 
			
		||||
                maxLength: CustomerConsts.MaxNameLength
 | 
			
		||||
            );
 | 
			
		||||
            this.firstName = firstName;
 | 
			
		||||
        }
 | 
			
		||||
        internal Customer ChangeLastName(string lastname)
 | 
			
		||||
        {
 | 
			
		||||
            SetLastName(lastname);
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SetLastName(string lastname)
 | 
			
		||||
        {
 | 
			
		||||
            lastname = Check.NotNullOrWhiteSpace(
 | 
			
		||||
                lastname,
 | 
			
		||||
                nameof(lastname),
 | 
			
		||||
                maxLength: CustomerConsts.MaxNameLength
 | 
			
		||||
            );
 | 
			
		||||
            this.lastName = lastname;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Customers
 | 
			
		||||
{
 | 
			
		||||
    public class CustomerErrorException : BusinessException
 | 
			
		||||
    {
 | 
			
		||||
        public CustomerErrorException(string phone)
 | 
			
		||||
            : base(BookStoreDomainErrorCodes.CustomerPhoneAlreadyExists)
 | 
			
		||||
        {
 | 
			
		||||
            WithData("phone", phone);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,55 +0,0 @@
 | 
			
		||||
using Acme.BookStore.Authors;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Guids;
 | 
			
		||||
using Volo.Abp;
 | 
			
		||||
using Volo.Abp.Domain.Services;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Customers
 | 
			
		||||
{
 | 
			
		||||
    
 | 
			
		||||
    public class CustomerManager : DomainService
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ICustomerRepository _customerRepository;
 | 
			
		||||
        public CustomerManager(ICustomerRepository customerRepository) 
 | 
			
		||||
        {
 | 
			
		||||
            _customerRepository = customerRepository;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<Customer> CreateAsync(
 | 
			
		||||
           Customer customer)
 | 
			
		||||
        {
 | 
			
		||||
            Check.NotNullOrWhiteSpace(customer.firstName, nameof(customer.firstName));
 | 
			
		||||
            Check.NotNullOrWhiteSpace(customer.lastName, nameof(customer.lastName));
 | 
			
		||||
 | 
			
		||||
            var existingAuthor = await _customerRepository.FindByPhoneAsync(customer.phone);
 | 
			
		||||
            if (existingAuthor != null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new CustomerErrorException(customer.phone);
 | 
			
		||||
            }
 | 
			
		||||
            return new Customer(
 | 
			
		||||
               await _customerRepository.NewCustomerId(),
 | 
			
		||||
                customer.firstName,
 | 
			
		||||
                    customer.lastName,
 | 
			
		||||
                customer.phone,
 | 
			
		||||
                customer.address
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task ChangeNameAsync(
 | 
			
		||||
         Customer customer,
 | 
			
		||||
          string firstName,string lastName)
 | 
			
		||||
        {
 | 
			
		||||
            Check.NotNull(customer, nameof(customer));
 | 
			
		||||
            Check.NotNullOrWhiteSpace(customer.firstName, nameof(customer.firstName));
 | 
			
		||||
            Check.NotNullOrWhiteSpace(customer.lastName, nameof(customer.lastName));
 | 
			
		||||
 | 
			
		||||
            customer.ChangeFirstName(firstName);
 | 
			
		||||
            customer.ChangeLastName(lastName);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
using Acme.BookStore.Authors;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Domain.Repositories;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Customers
 | 
			
		||||
{
 | 
			
		||||
    public interface ICustomerRepository : IRepository<Customer, int>
 | 
			
		||||
    {
 | 
			
		||||
        Task<Customer> FindByPhoneAsync(string phone);
 | 
			
		||||
        Task<int> NewCustomerId();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <Import Project="..\..\common.props" />
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,56 +0,0 @@
 | 
			
		||||
using Acme.BookStore.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
 | 
			
		||||
using Volo.Abp.EntityFrameworkCore;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Authors
 | 
			
		||||
{
 | 
			
		||||
    public class EfCoreAuthorRepository
 | 
			
		||||
    : EfCoreRepository<BookStoreDbContext, Author, Guid>,
 | 
			
		||||
        IAuthorRepository
 | 
			
		||||
    {
 | 
			
		||||
        public EfCoreAuthorRepository(
 | 
			
		||||
            IDbContextProvider<BookStoreDbContext> dbContextProvider)
 | 
			
		||||
            : base(dbContextProvider)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<Author> FindByNameAsync(string name)
 | 
			
		||||
        {
 | 
			
		||||
            var dbSet = await GetDbSetAsync();
 | 
			
		||||
            return await dbSet.FirstOrDefaultAsync(author => author.Name == name);
 | 
			
		||||
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<List<Author>> GetListAsync(
 | 
			
		||||
            int skipCount,
 | 
			
		||||
            int maxResultCount,
 | 
			
		||||
            string sorting,
 | 
			
		||||
            string filter = null)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
            var dbSet = await GetDbSetAsync();
 | 
			
		||||
 | 
			
		||||
            return await dbSet.WhereIf(
 | 
			
		||||
                !filter.IsNullOrEmpty(),
 | 
			
		||||
                author=>author.Name.Contains(filter)).OrderBy(author=> author.Name).Skip(skipCount).Take(maxResultCount).ToListAsync();
 | 
			
		||||
 | 
			
		||||
            //return await dbSet
 | 
			
		||||
            //   .WhereIf(
 | 
			
		||||
            //       !filter.IsNullOrWhiteSpace(),
 | 
			
		||||
            //       author => author.Name.Contains(filter)
 | 
			
		||||
            //       )
 | 
			
		||||
            //   .OrderBy(sorting)
 | 
			
		||||
            //   .Skip(skipCount)
 | 
			
		||||
            //   .Take(maxResultCount)
 | 
			
		||||
            //   .ToListAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,85 +0,0 @@
 | 
			
		||||
using Acme.BookStore.Customers;
 | 
			
		||||
using Acme.BookStore.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Polly;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp;
 | 
			
		||||
using Volo.Abp.Data;
 | 
			
		||||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
 | 
			
		||||
using Volo.Abp.EntityFrameworkCore;
 | 
			
		||||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.BookIssued
 | 
			
		||||
{
 | 
			
		||||
    public class EfCoreBookIssueRepository : EfCoreRepository<BookStoreDbContext, BookIssue, int>,
 | 
			
		||||
        IBookIssueRepository
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IDataFilter _dataFilter;
 | 
			
		||||
 | 
			
		||||
        public EfCoreBookIssueRepository(
 | 
			
		||||
            IDbContextProvider<BookStoreDbContext> dbContextProvider, IDataFilter dataFilter
 | 
			
		||||
)
 | 
			
		||||
            : base(dbContextProvider)
 | 
			
		||||
        {
 | 
			
		||||
            _dataFilter = dataFilter;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        public async Task<BookIssueList> FindBookIssueCustomer(int customerId, Guid bookId)
 | 
			
		||||
        {
 | 
			
		||||
            //var dbSet = await GetDbSetAsync();
 | 
			
		||||
 | 
			
		||||
            var dbContext = await GetDbContextAsync();
 | 
			
		||||
 | 
			
		||||
            List<BookIssueList> item = (
 | 
			
		||||
            from bi in dbContext.bookIssues
 | 
			
		||||
            join cu in dbContext.Customers on bi.customerId equals cu.Id
 | 
			
		||||
            join bk in dbContext.Books on bi.bookId equals bk.Id
 | 
			
		||||
            where (bi.customerId == customerId && bi.bookId == bookId && bi.IsDeleted == false)
 | 
			
		||||
            select new BookIssueList
 | 
			
		||||
            {
 | 
			
		||||
                bookIssueId = bi.Id,
 | 
			
		||||
                bookName = bk.Name,
 | 
			
		||||
                customerName = cu.firstName + " " + cu.lastName,
 | 
			
		||||
                issueDate = bi.CreationTime
 | 
			
		||||
            }).ToList();
 | 
			
		||||
 | 
			
		||||
            return item == null? null : item.FirstOrDefault();
 | 
			
		||||
             
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<int> NewBookIssueId()
 | 
			
		||||
        {
 | 
			
		||||
            using (_dataFilter.Disable<ISoftDelete>())
 | 
			
		||||
            {
 | 
			
		||||
                var dbSet = await GetDbSetAsync();
 | 
			
		||||
                var values = await dbSet.MaxAsync(u => (int?)u.Id);
 | 
			
		||||
                return values == null ? 0 + 1 : (int)values + 1;
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<List<BookIssueList>> BookIssueList()
 | 
			
		||||
        {
 | 
			
		||||
            var dbContext = await GetDbContextAsync();
 | 
			
		||||
 | 
			
		||||
            List<BookIssueList> item = (
 | 
			
		||||
            from bi in dbContext.bookIssues
 | 
			
		||||
            join cu in dbContext.Customers on bi.customerId equals cu.Id
 | 
			
		||||
            join bk in dbContext.Books on bi.bookId equals bk.Id
 | 
			
		||||
            select new BookIssueList
 | 
			
		||||
            {
 | 
			
		||||
                bookIssueId = bi.Id,
 | 
			
		||||
                bookName = bk.Name,
 | 
			
		||||
                customerName = cu.firstName + " " + cu.lastName,
 | 
			
		||||
                issueDate = bi.CreationTime
 | 
			
		||||
            }).ToList();
 | 
			
		||||
 | 
			
		||||
            return item;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,40 +0,0 @@
 | 
			
		||||
using Acme.BookStore.Authors;
 | 
			
		||||
using Acme.BookStore.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
 | 
			
		||||
using Volo.Abp.EntityFrameworkCore;
 | 
			
		||||
 | 
			
		||||
namespace Acme.BookStore.Customers
 | 
			
		||||
{
 | 
			
		||||
    public class EfCoreCustomerRepository : EfCoreRepository<BookStoreDbContext, Customer, int>,
 | 
			
		||||
        ICustomerRepository
 | 
			
		||||
    {
 | 
			
		||||
        public EfCoreCustomerRepository(
 | 
			
		||||
            IDbContextProvider<BookStoreDbContext> dbContextProvider)
 | 
			
		||||
            : base(dbContextProvider)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<Customer> FindByPhoneAsync(string phone)
 | 
			
		||||
        {
 | 
			
		||||
            var dbSet = await GetDbSetAsync();
 | 
			
		||||
            return await dbSet.FirstOrDefaultAsync(cust => cust.phone == phone);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<int>  NewCustomerId()
 | 
			
		||||
        {
 | 
			
		||||
            var dbSet = await GetDbSetAsync();
 | 
			
		||||
            var values = await dbSet.MaxAsync(u => (int?)u.Id);
 | 
			
		||||
            return values == null ? 0 +1: (int)values + 1;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,14 +1,9 @@
 | 
			
		||||
using Acme.BookStore.Authors;
 | 
			
		||||
using Acme.BookStore.BookIssued;
 | 
			
		||||
using Acme.BookStore.Books;
 | 
			
		||||
using Acme.BookStore.Customers;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Volo.Abp.AuditLogging.EntityFrameworkCore;
 | 
			
		||||
using Volo.Abp.BackgroundJobs.EntityFrameworkCore;
 | 
			
		||||
using Volo.Abp.Data;
 | 
			
		||||
using Volo.Abp.DependencyInjection;
 | 
			
		||||
using Volo.Abp.EntityFrameworkCore;
 | 
			
		||||
using Volo.Abp.EntityFrameworkCore.Modeling;
 | 
			
		||||
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
 | 
			
		||||
using Volo.Abp.Identity;
 | 
			
		||||
using Volo.Abp.Identity.EntityFrameworkCore;
 | 
			
		||||
@ -55,12 +50,6 @@ public class BookStoreDbContext :
 | 
			
		||||
    // Tenant Management
 | 
			
		||||
    public DbSet<Tenant> Tenants { get; set; }
 | 
			
		||||
    public DbSet<TenantConnectionString> TenantConnectionStrings { get; set; }
 | 
			
		||||
    public DbSet<Book> Books { get; set; }
 | 
			
		||||
 | 
			
		||||
    public DbSet<Author> Authors { get; set; }
 | 
			
		||||
    public DbSet<Customer> Customers { get; set; }
 | 
			
		||||
    public DbSet<BookIssue> bookIssues { get; set; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
@ -85,59 +74,6 @@ public class BookStoreDbContext :
 | 
			
		||||
        builder.ConfigureFeatureManagement();
 | 
			
		||||
        builder.ConfigureTenantManagement();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        builder.Entity<Book>(b =>
 | 
			
		||||
        {
 | 
			
		||||
            b.ToTable(BookStoreConsts.DbTablePrefix + "Books",
 | 
			
		||||
                BookStoreConsts.DbSchema);
 | 
			
		||||
            b.ConfigureByConvention(); //auto configure for the base class props
 | 
			
		||||
            b.Property(x => x.Name).IsRequired().HasMaxLength(128);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        builder.Entity<Author>(b =>
 | 
			
		||||
        {
 | 
			
		||||
            b.ToTable(BookStoreConsts.DbTablePrefix + "Authors",
 | 
			
		||||
                BookStoreConsts.DbSchema);
 | 
			
		||||
 | 
			
		||||
            b.ConfigureByConvention();
 | 
			
		||||
 | 
			
		||||
            b.Property(x => x.Name)
 | 
			
		||||
                .IsRequired()
 | 
			
		||||
                .HasMaxLength(AuthorConsts.MaxNameLength);
 | 
			
		||||
 | 
			
		||||
            b.HasIndex(x => x.Name);
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        builder.Entity<Customer>(b =>
 | 
			
		||||
        {
 | 
			
		||||
            b.ToTable(BookStoreConsts.DbTablePrefix + "Customers",
 | 
			
		||||
                BookStoreConsts.DbSchema);
 | 
			
		||||
 | 
			
		||||
            b.ConfigureByConvention();
 | 
			
		||||
 | 
			
		||||
            b.Property(x => x.firstName)
 | 
			
		||||
                .IsRequired()
 | 
			
		||||
                .HasMaxLength(CustomerConsts.MaxNameLength);
 | 
			
		||||
            
 | 
			
		||||
            b.Property(x => x.lastName)
 | 
			
		||||
                .IsRequired()
 | 
			
		||||
                .HasMaxLength(CustomerConsts.MaxNameLength);
 | 
			
		||||
 | 
			
		||||
            b.Property(x => x.phone)
 | 
			
		||||
                .IsRequired()
 | 
			
		||||
                .HasMaxLength(CustomerConsts.MaxPhoneLength); 
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        builder.Entity<BookIssue>(b =>
 | 
			
		||||
        {
 | 
			
		||||
            b.ToTable(BookStoreConsts.DbTablePrefix + "BookIssued",
 | 
			
		||||
               "BKN");
 | 
			
		||||
              
 | 
			
		||||
            b.ConfigureByConvention();
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        /* Configure your own tables/entities inside here */
 | 
			
		||||
 | 
			
		||||
        //builder.Entity<YourEntity>(b =>
 | 
			
		||||
 | 
			
		||||