Skip to content

Commit

Permalink
circulation: add manuel fee
Browse files Browse the repository at this point in the history
Co-Authored-by: Bertrand Zuchuat <bertrand.zuchuat@rero.ch>
  • Loading branch information
Garfield-fr committed Jan 18, 2023
1 parent c3a010f commit 926b77b
Show file tree
Hide file tree
Showing 12 changed files with 350 additions and 21 deletions.
1 change: 1 addition & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"styles": [
"node_modules/primeng/resources/themes/lara-light-blue/theme.css",
"node_modules/primeng/resources/primeng.min.css",
"node_modules/primeicons/primeicons.css",
"projects/admin/src/app/scss/styles.scss",
"node_modules/ngx-bootstrap/datepicker/bs-datepicker.css"
],
Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,14 @@
"font-awesome": "^4.7.0",
"issn": "^1.0.6",
"lodash-es": "^4.17.21",
"luxon": "^3.1.1",
"marked": "^4.1.1",
"moment": "^2.29.1",
"ngx-bootstrap": "^9.0.0",
"ngx-build-plus": "^14.0.0",
"ngx-spinner": "^14.0.0",
"ngx-toastr": "^15.2.0",
"primeicons": "^6.0.1",
"primeng": "^14.2.2",
"rxjs": "~6.6.7",
"simple-isbn": "^1.1.5",
Expand Down
44 changes: 44 additions & 0 deletions projects/admin/src/app/api/patron-transaction-api.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* RERO ILS UI
* Copyright (C) 2022-2023 RERO
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ApiService } from '@rero/ng-core';
import { Observable } from 'rxjs';
import { FeeFormModel } from '../circulation/patron/patron-transactions/patron-fee/patron-fee.component';

@Injectable({
providedIn: 'root'
})
export class PatronTransactionApiService {

/**
* Constructor
* @param _httpClient - HttpClient
*/
constructor(
private _httpClient: HttpClient,
private _apiService: ApiService
) {}

/**
* Add fee
* @return Observable, array of records
*/
addFee(model: FeeFormModel): Observable<Object> {
return this._httpClient.post(this._apiService.getEndpointByType('patron_transactions/'), model);
}
}
4 changes: 3 additions & 1 deletion projects/admin/src/app/circulation/circulation.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import { PickupComponent } from './patron/pickup/pickup.component';
import { ProfileComponent } from './patron/profile/profile.component';
import { GetLoanCipoPipe } from './pipe/get-loan-cipo.pipe';
import { CheckinActionComponent } from './checkin/checkin-action/checkin-action.component';
import { PatronFeeComponent } from './patron/patron-transactions/patron-fee/patron-fee.component';


@NgModule({
Expand Down Expand Up @@ -93,7 +94,8 @@ import { CheckinActionComponent } from './checkin/checkin-action/checkin-action.
HistoryLogComponent,
HistoryLogLibraryComponent,
GetLoanCipoPipe,
CheckinActionComponent
CheckinActionComponent,
PatronFeeComponent
],
imports: [
BsDropdownModule.forRoot(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!--
RERO ILS UI
Copyright (C) 2022 RERO
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<div *ngIf="form" class="modal show d-block" role="dialog">
<div class="modal-dialog modal-dialog-centered" role="fee">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" translate>New fee</h5>
</div>
<div class="modal-body">
<form [formGroup]="form" (ngSubmit)="submit(model)">
<formly-form [form]="form" [fields]="formFields" [model]="model"></formly-form>
<div class="text-right">
<a class="btn btn-sm btn-outline-danger mr-1" (click)="closeModal()" translate>Cancel</a>
<button type="submit" class="btn btn-sm btn-primary" [disabled]="!form.valid" translate>Save</button>
</div>
</form>
</div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
/*
* RERO ILS UI
* Copyright (C) 2022 RERO
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { getCurrencySymbol } from '@angular/common';
import { Component, EventEmitter, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FormlyFieldConfig } from '@ngx-formly/core';
import { TranslateService } from '@ngx-translate/core';
import { ApiService, RecordService } from '@rero/ng-core';
import { UserService } from '@rero/shared';
import { BsModalRef } from 'ngx-bootstrap/modal';
import { ToastrService } from 'ngx-toastr';
import { PatronTransactionApiService } from 'projects/admin/src/app/api/patron-transaction-api.service';
import { OrganisationService } from 'projects/admin/src/app/service/organisation.service';

import { DateTime } from 'luxon';

@Component({
selector: 'admin-patron-fee',
templateUrl: './patron-fee.component.html',
styles: ['.p-inputtext { width: 100%; padding: 0 }']
})
export class PatronFeeComponent implements OnInit {

/** Patron pid */
@Input() patronPid: string;

/** Organisation pid */
@Input() organisationPid: string;

/** form */
form: FormGroup = new FormGroup({});

/** form fields */
formFields: FormlyFieldConfig[];

/** model */
model: FeeFormModel;

/** On submit event */
onSubmit: EventEmitter<any> = new EventEmitter();

/**
* Constructor
* @param _recordService - RecordService
* @param _bsModalRef - BsModalRef
* @param _toastr - ToastrService
* @param _translateService - TranslateService
* @param _organisationService - OrganisationService
* @param _userService - UserService
* @param _patronTransactionApiService - PatronTransactionApiService
* @param _apiService - ApiService
*/
constructor(
private _recordService: RecordService,
private _bsModalRef: BsModalRef,
private _toastr: ToastrService,
private _translateService: TranslateService,
private _organisationService: OrganisationService,
private _userService: UserService,
private _patronTransactionApiService: PatronTransactionApiService,
private _apiService: ApiService
) { }

/** OnInit Hook */
ngOnInit(): void {
if (!this.patronPid) {
this.closeModal();
}
const librarySchema$ = this._recordService.getSchemaForm('patron_transactions');
librarySchema$.subscribe((schema: any) => {
this._initForm(schema.schema.properties);
});
}

/**
* Submit the form
* @param model - Fee model
*/
submit(model: FeeFormModel): void {
if (model.creation_date instanceof Date) {
model.creation_date = DateTime.fromObject(model.creation_date).toISO();
}
this._patronTransactionApiService.addFee(model).subscribe(
() => {
this.onSubmit.next('submit');
this.closeModal();
this._toastr.success(
this._translateService.instant('Added a new fee.'),
this._translateService.instant('Patron transaction')
);
},
() => {
this._toastr.error(
this._translateService.instant('An error has occurred. Please try again.'),
this._translateService.instant('Patron transaction'),
{ disableTimeOut: true }
);
}
);
}

/** Close modal box */
closeModal(): void {
this._bsModalRef.hide();
}

/** Init form model */
private _initForm(properties: any): void
{
this.formFields = [
{
key: 'type',
type: 'selectWithSort',
templateOptions: {
label: 'Type',
required: true,
options: properties.type.form.options
}
},
{
key: 'total_amount',
type: 'input',
templateOptions: {
type: 'number',
label: 'Amount',
required: true,
addonLeft: {
text: getCurrencySymbol(this._organisationService.organisation.default_currency, 'wide')
}
}
},
{
key: 'note',
type: 'input',
templateOptions: {
label: 'Note'
}
},
{
key: 'creation_date',
type: 'dateTimePicker',
wrappers: ['form-field'],
templateOptions: {
label: 'Date',
required: true,
dateFormat: 'yy-mm-dd',
}
}
];

// Default model value
this.model = {
type: null,
total_amount: null,
creation_date: new Date(),
patron: {
$ref: this._apiService.getRefEndpoint('patrons', this.patronPid)
},
organisation: {
$ref: this._apiService.getRefEndpoint('organisations', this.organisationPid)
},
library: {
$ref: this._apiService.getRefEndpoint('libraries', this._userService.user.currentLibrary)
},
status: 'open',
event: {
operator: {
$ref: this._apiService.getRefEndpoint('patrons', this._userService.user.patronLibrarian.pid)
},
library: {
$ref: this._apiService.getRefEndpoint('libraries', this._userService.user.currentLibrary)
}
}
}
}
}

/** Interface to define fields on form */
export interface FeeFormModel {
type: string;
total_amount: number;
note?: string;
creation_date: any;
patron: {
$ref: string;
},
library: {
$ref: string
}
organisation: {
$ref: string;
};
status: string;
event: {
operator: {
$ref: string;
},
library: {
$ref: string
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
</button>
{{ transaction.creation_date | dateTranslate :'shortDate' }}
</div>
<div class="col-lg-4 d-inline-block text-truncate">{{ label }}</div>
<div class="col-lg-4 d-inline-block text-truncate">{{ transaction.type | translate }}</div>
<div class="col-lg-3 d-inline-block text-truncate"><span *ngIf="transaction.library">{{ transaction.library.pid | getRecord: 'libraries' : 'field' : 'name' | async }}</span></div>
<div class="col-lg-2 text-lg-right">{{ transactionAmount | currency: organisation.default_currency }}</div>
<div class="col-md-1 text-left pl-0 mb-2" dropdown>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,6 @@ export class PatronTransactionComponent implements OnInit {


// COMPONENT FUNCTIONS ========================================================
/**
* Get the label of the transaction depending of transaction.type
* @return label/title of the transaction as string
*/
get label(): string {
return (this.transaction.type === 'other')
? this.transaction.note
: this._translateService.instant(this.transaction.type);
}

/** Check if the transaction contains a 'dispute' linked event
* @return: True if transaction is still open and contains a 'dispute' event; False otherwise
Expand Down
Loading

0 comments on commit 926b77b

Please sign in to comment.