This commit is contained in:
parent
569a0e8cc9
commit
704cb71b61
|
@ -1,6 +1,6 @@
|
||||||
const models = require('vn-loopback/server/server').models;
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('ticket getCollection()', () => {
|
fdescribe('ticket getCollection()', () => {
|
||||||
it('should return a list of collections', async() => {
|
it('should return a list of collections', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 1107}}};
|
let ctx = {req: {accessToken: {userId: 1107}}};
|
||||||
let response = await models.Collection.getCollection(ctx);
|
let response = await models.Collection.getCollection(ctx);
|
||||||
|
|
|
@ -678,7 +678,10 @@ export default {
|
||||||
moveToTicketButton: '.vn-popover.shown vn-icon[icon="arrow_forward_ios"]',
|
moveToTicketButton: '.vn-popover.shown vn-icon[icon="arrow_forward_ios"]',
|
||||||
moveToNewTicketButton: '.vn-popover.shown vn-button[label="New ticket"]',
|
moveToNewTicketButton: '.vn-popover.shown vn-button[label="New ticket"]',
|
||||||
stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="State"]',
|
stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="State"]',
|
||||||
moreMenuState: 'body > div > div > div.content > div.filter.ng-scope > vn-textfield'
|
moreMenuState: 'body > div > div > div.content > div.filter.ng-scope > vn-textfield',
|
||||||
|
firstSaleHistoryButton: 'vn-ticket-sale vn-tr:nth-child(1) vn-icon-button[icon="history"]',
|
||||||
|
firstSaleHistory: 'form vn-table div > vn-tbody > vn-tr',
|
||||||
|
closeHistory: 'div.window vn-button[icon="clear"]'
|
||||||
},
|
},
|
||||||
ticketTracking: {
|
ticketTracking: {
|
||||||
createStateButton: 'vn-float-button'
|
createStateButton: 'vn-float-button'
|
||||||
|
|
|
@ -196,6 +196,15 @@ describe('Ticket Edit sale path', () => {
|
||||||
expect(result).toContain('22.50');
|
expect(result).toContain('22.50');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should check in the history that logs has been added', async() => {
|
||||||
|
await page.waitToClick(selectors.ticketSales.firstSaleHistoryButton);
|
||||||
|
await page.waitForSelector(selectors.ticketSales.firstSaleHistory);
|
||||||
|
const result = await page.countElement(selectors.ticketSales.firstSaleHistory);
|
||||||
|
|
||||||
|
expect(result).toBeGreaterThan(0);
|
||||||
|
await page.waitToClick(selectors.ticketSales.closeHistory);
|
||||||
|
});
|
||||||
|
|
||||||
it('should recalculate price of sales', async() => {
|
it('should recalculate price of sales', async() => {
|
||||||
await page.waitToClick(selectors.ticketSales.firstSaleCheckbox);
|
await page.waitToClick(selectors.ticketSales.firstSaleCheckbox);
|
||||||
await page.waitToClick(selectors.ticketSales.secondSaleCheckbox);
|
await page.waitToClick(selectors.ticketSales.secondSaleCheckbox);
|
||||||
|
|
|
@ -19,3 +19,4 @@ import './user-popover';
|
||||||
import './upload-photo';
|
import './upload-photo';
|
||||||
import './bank-entity';
|
import './bank-entity';
|
||||||
import './log';
|
import './log';
|
||||||
|
import './instance-log';
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
|
||||||
|
<vn-dialog
|
||||||
|
vn-id="instanceLog">
|
||||||
|
<tpl-body>
|
||||||
|
<vn-crud-model
|
||||||
|
vn-id="model"
|
||||||
|
url="{{$ctrl.url}}"
|
||||||
|
filter="$ctrl.filter"
|
||||||
|
link="{originFk: $ctrl.originId}"
|
||||||
|
data="$ctrl.logs"
|
||||||
|
limit="20"
|
||||||
|
auto-load="true">
|
||||||
|
</vn-crud-model>
|
||||||
|
<vn-data-viewer model="model">
|
||||||
|
<vn-table model="model">
|
||||||
|
<vn-thead>
|
||||||
|
<vn-tr>
|
||||||
|
<vn-th field="creationDate">Date</vn-th>
|
||||||
|
<vn-th field="userFk" shrink>User</vn-th>
|
||||||
|
<vn-th field="action" shrink>Action</vn-th>
|
||||||
|
<vn-th expand>Changes</vn-th>
|
||||||
|
</vn-tr>
|
||||||
|
</vn-thead>
|
||||||
|
<vn-tbody>
|
||||||
|
<vn-tr ng-repeat="log in $ctrl.logs">
|
||||||
|
<vn-td shrink-datetime>
|
||||||
|
{{::log.creationDate | date:'dd/MM/yyyy HH:mm'}}
|
||||||
|
</vn-td>
|
||||||
|
<vn-td>
|
||||||
|
<span ng-class="{'link': log.user.worker.id, 'value': !log.user.worker.id}"
|
||||||
|
ng-click="$ctrl.showWorkerDescriptor($event, log.user.worker.id)"
|
||||||
|
translate>{{::log.user.name || 'System' | translate}}
|
||||||
|
</span>
|
||||||
|
</vn-td>
|
||||||
|
<vn-td translate>
|
||||||
|
{{::$ctrl.actionsText[log.action]}}
|
||||||
|
</vn-td>
|
||||||
|
<vn-td expand>
|
||||||
|
<table class="attributes">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th translate class="field">Field</th>
|
||||||
|
<th translate>Before</th>
|
||||||
|
<th translate>After</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="prop in ::log.props">
|
||||||
|
<td class="field">{{prop.name}}</td>
|
||||||
|
<td class="before">{{::$ctrl.formatValue(prop.old)}}</td>
|
||||||
|
<td class="after">{{::$ctrl.formatValue(prop.new)}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<vn-one ng-if="!log.newProperties" id="description">
|
||||||
|
<div>
|
||||||
|
<span no-ellipsize>{{::log.description}}</span>
|
||||||
|
</div>
|
||||||
|
</vn-one>
|
||||||
|
</vn-td>
|
||||||
|
</vn-tr>
|
||||||
|
</vn-tbody>
|
||||||
|
</vn-table>
|
||||||
|
<vn-pagination model="model"></vn-pagination>
|
||||||
|
</vn-data-viewer>
|
||||||
|
</tpl-body>
|
||||||
|
</vn-dialog>
|
||||||
|
<vn-worker-descriptor-popover vn-id="workerDescriptor">
|
||||||
|
</vn-worker-descriptor-popover>
|
|
@ -0,0 +1,106 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import './style.scss';
|
||||||
|
import Section from '../section';
|
||||||
|
|
||||||
|
export default class Controller extends Section {
|
||||||
|
constructor($element, $) {
|
||||||
|
super($element, $);
|
||||||
|
this.actionsText = {
|
||||||
|
'insert': 'Creates',
|
||||||
|
'update': 'Updates',
|
||||||
|
'delete': 'Deletes',
|
||||||
|
'select': 'Views'
|
||||||
|
}; ``;
|
||||||
|
}
|
||||||
|
|
||||||
|
open() {
|
||||||
|
this.filter = {
|
||||||
|
where:
|
||||||
|
{changedModel: this.changedModel,
|
||||||
|
changedModelId: this.changedModelId},
|
||||||
|
include: [{
|
||||||
|
relation: 'user',
|
||||||
|
scope: {
|
||||||
|
fields: ['name'],
|
||||||
|
include: {
|
||||||
|
relation: 'worker',
|
||||||
|
scope: {
|
||||||
|
fields: ['id']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
this.$.instanceLog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
get logs() {
|
||||||
|
return this._logs;
|
||||||
|
}
|
||||||
|
|
||||||
|
set logs(value) {
|
||||||
|
this._logs = value;
|
||||||
|
if (!this.logs) return;
|
||||||
|
const validations = window.validations;
|
||||||
|
for (const log of value) {
|
||||||
|
const locale = validations[log.changedModel] && validations[log.changedModel].locale
|
||||||
|
? validations[log.changedModel].locale : {};
|
||||||
|
log.oldProperties = this.getInstance(log.oldInstance, locale);
|
||||||
|
log.newProperties = this.getInstance(log.newInstance, locale);
|
||||||
|
let props = [].concat(log.oldProperties.map(p => p.key), log.newProperties.map(p => p.key));
|
||||||
|
props = [...new Set(props)];
|
||||||
|
log.props = [];
|
||||||
|
for (const prop of props) {
|
||||||
|
const matchOldProp = log.oldProperties.find(p => p.key === prop);
|
||||||
|
const matchNewProp = log.newProperties.find(p => p.key === prop);
|
||||||
|
log.props.push({
|
||||||
|
name: prop,
|
||||||
|
old: matchOldProp ? matchOldProp.value : null,
|
||||||
|
new: matchNewProp ? matchNewProp.value : null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
formatValue(value) {
|
||||||
|
switch (typeof value) {
|
||||||
|
case 'boolean':
|
||||||
|
return value ? '✓' : '✗';
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getInstance(instance, locale) {
|
||||||
|
const properties = [];
|
||||||
|
let validDate = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/;
|
||||||
|
|
||||||
|
if (typeof instance == 'object' && instance != null) {
|
||||||
|
Object.keys(instance).forEach(property => {
|
||||||
|
if (validDate.test(instance[property]))
|
||||||
|
instance[property] = new Date(instance[property]).toLocaleString('es-ES');
|
||||||
|
const key = locale[property] || property;
|
||||||
|
properties.push({key, value: instance[property]});
|
||||||
|
});
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
showWorkerDescriptor(event, workerId) {
|
||||||
|
if (!workerId) return;
|
||||||
|
this.$.workerDescriptor.show(event.target, workerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngModule.vnComponent('vnInstanceLog', {
|
||||||
|
controller: Controller,
|
||||||
|
template: require('./index.html'),
|
||||||
|
bindings: {
|
||||||
|
model: '<',
|
||||||
|
originId: '<',
|
||||||
|
changedModel: '<',
|
||||||
|
changedModelId: '<',
|
||||||
|
url: '@'
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,15 @@
|
||||||
|
Date: Fecha
|
||||||
|
Model: Modelo
|
||||||
|
Action: Acción
|
||||||
|
Author: Autor
|
||||||
|
Before: Antes
|
||||||
|
After: Despues
|
||||||
|
History: Historial
|
||||||
|
Name: Nombre
|
||||||
|
Creates: Crea
|
||||||
|
Updates: Actualiza
|
||||||
|
Deletes: Elimina
|
||||||
|
Views: Visualiza
|
||||||
|
System: Sistema
|
||||||
|
note: nota
|
||||||
|
Changes: Cambios
|
|
@ -0,0 +1,43 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
vn-instance-log {
|
||||||
|
vn-td {
|
||||||
|
vertical-align: initial !important;
|
||||||
|
}
|
||||||
|
.changes {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
color: $color-font-secondary;
|
||||||
|
}
|
||||||
|
.value {
|
||||||
|
color: $color-font;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1570px) {
|
||||||
|
vn-table .expendable {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.changes {
|
||||||
|
padding-top: 10px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.attributes {
|
||||||
|
width: 100%;
|
||||||
|
white-space: inherit !important;
|
||||||
|
|
||||||
|
tr {
|
||||||
|
height: 10px;
|
||||||
|
|
||||||
|
& > td {
|
||||||
|
padding: 2px;
|
||||||
|
width: 33%;
|
||||||
|
}
|
||||||
|
& > td.field,
|
||||||
|
& > th.field {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,7 +30,7 @@
|
||||||
ng-click="moreOptions.show($event)"
|
ng-click="moreOptions.show($event)"
|
||||||
ng-show="$ctrl.hasSelectedSales()">
|
ng-show="$ctrl.hasSelectedSales()">
|
||||||
</vn-button>
|
</vn-button>
|
||||||
<vn-button
|
<vn-button
|
||||||
disabled="!$ctrl.hasSelectedSales() || !$ctrl.isEditable"
|
disabled="!$ctrl.hasSelectedSales() || !$ctrl.isEditable"
|
||||||
ng-click="deleteLines.show()"
|
ng-click="deleteLines.show()"
|
||||||
vn-tooltip="Remove lines"
|
vn-tooltip="Remove lines"
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
<vn-thead>
|
<vn-thead>
|
||||||
<vn-tr>
|
<vn-tr>
|
||||||
<vn-th shrink>
|
<vn-th shrink>
|
||||||
<vn-multi-check model="model"
|
<vn-multi-check model="model"
|
||||||
on-change="$ctrl.resetChanges()">
|
on-change="$ctrl.resetChanges()">
|
||||||
</vn-multi-check>
|
</vn-multi-check>
|
||||||
</vn-th>
|
</vn-th>
|
||||||
|
@ -68,6 +68,7 @@
|
||||||
<vn-th number>Disc</vn-th>
|
<vn-th number>Disc</vn-th>
|
||||||
<vn-th number>Amount</vn-th>
|
<vn-th number>Amount</vn-th>
|
||||||
<vn-th shrink>Packaging</vn-th>
|
<vn-th shrink>Packaging</vn-th>
|
||||||
|
<vn-th shrink></vn-th>
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-thead>
|
</vn-thead>
|
||||||
<vn-tbody>
|
<vn-tbody>
|
||||||
|
@ -84,13 +85,13 @@
|
||||||
vn-tooltip="{{::$ctrl.$t('Claim')}}: {{::sale.claim.claimFk}}">
|
vn-tooltip="{{::$ctrl.$t('Claim')}}: {{::sale.claim.claimFk}}">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
</a>
|
</a>
|
||||||
<vn-icon
|
<vn-icon
|
||||||
ng-show="::(sale.visible < 0)"
|
ng-show="::(sale.visible < 0)"
|
||||||
color-main
|
color-main
|
||||||
icon="warning"
|
icon="warning"
|
||||||
vn-tooltip="Visible: {{::sale.visible || 0}}">
|
vn-tooltip="Visible: {{::sale.visible || 0}}">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
<vn-icon ng-show="sale.reserved"
|
<vn-icon ng-show="sale.reserved"
|
||||||
icon="icon-reserve"
|
icon="icon-reserve"
|
||||||
translate-attr="{title: 'Reserved'}">
|
translate-attr="{title: 'Reserved'}">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
|
@ -108,21 +109,21 @@
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
<img
|
<img
|
||||||
ng-src="{{$root.imagePath('catalog', '50x50', sale.itemFk)}}"
|
ng-src="{{$root.imagePath('catalog', '50x50', sale.itemFk)}}"
|
||||||
zoom-image="{{$root.imagePath('catalog', '1600x900', sale.itemFk)}}"
|
zoom-image="{{$root.imagePath('catalog', '1600x900', sale.itemFk)}}"
|
||||||
on-error-src/>
|
on-error-src/>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
<vn-chip
|
<vn-chip
|
||||||
class="transparent"
|
class="transparent"
|
||||||
ng-class="{'alert': sale.visible < 0}">
|
ng-class="{'alert': sale.visible < 0}">
|
||||||
{{::sale.visible}}
|
{{::sale.visible}}
|
||||||
</vn-chip>
|
</vn-chip>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
<vn-chip
|
<vn-chip
|
||||||
class="transparent"
|
class="transparent"
|
||||||
ng-class="{'alert': sale.available < 0}">
|
ng-class="{'alert': sale.available < 0}">
|
||||||
{{::sale.available}}
|
{{::sale.available}}
|
||||||
</vn-chip>
|
</vn-chip>
|
||||||
|
@ -195,7 +196,7 @@
|
||||||
translate-attr="{title: !$ctrl.isLocked ? 'Edit discount' : ''}"
|
translate-attr="{title: !$ctrl.isLocked ? 'Edit discount' : ''}"
|
||||||
ng-click="$ctrl.showEditDiscountPopover($event, sale)"
|
ng-click="$ctrl.showEditDiscountPopover($event, sale)"
|
||||||
ng-if="sale.id">
|
ng-if="sale.id">
|
||||||
{{(sale.discount / 100) | percentage}}
|
{{(sale.discount / 100) | percentage}}
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td number>
|
<vn-td number>
|
||||||
|
@ -204,6 +205,22 @@
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
{{::sale.item.itemPackingTypeFk | dashIfEmpty}}
|
{{::sale.item.itemPackingTypeFk | dashIfEmpty}}
|
||||||
</vn-td>
|
</vn-td>
|
||||||
|
<vn-td shrink>
|
||||||
|
<vn-icon-button
|
||||||
|
vn-none
|
||||||
|
vn-tooltip="History"
|
||||||
|
icon="history"
|
||||||
|
ng-click="log.open()">
|
||||||
|
</vn-icon-button>
|
||||||
|
<vn-instance-log
|
||||||
|
vn-id="log"
|
||||||
|
url="TicketLogs"
|
||||||
|
origin-id="$ctrl.$params.id"
|
||||||
|
changed-model="Sale"
|
||||||
|
changed-model-id="sale.id">
|
||||||
|
</vn-instance-log>
|
||||||
|
</vn-td>
|
||||||
|
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-tbody>
|
</vn-tbody>
|
||||||
</vn-table>
|
</vn-table>
|
||||||
|
@ -383,8 +400,8 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr
|
<tr
|
||||||
class="clickable"
|
class="clickable"
|
||||||
ng-repeat="ticket in $ctrl.transfer.lastActiveTickets track by ticket.id"
|
ng-repeat="ticket in $ctrl.transfer.lastActiveTickets track by ticket.id"
|
||||||
ng-click="$ctrl.transferSales(ticket.id)">
|
ng-click="$ctrl.transferSales(ticket.id)">
|
||||||
<td shrink>{{::ticket.id}}</td>
|
<td shrink>{{::ticket.id}}</td>
|
||||||
|
@ -392,22 +409,22 @@
|
||||||
<td shrink>{{::ticket.agencyName}}</td>
|
<td shrink>{{::ticket.agencyName}}</td>
|
||||||
<td expand>{{::ticket.address}}
|
<td expand>{{::ticket.address}}
|
||||||
<span vn-tooltip="
|
<span vn-tooltip="
|
||||||
{{::ticket.nickname}}
|
{{::ticket.nickname}}
|
||||||
{{::ticket.name}}
|
{{::ticket.name}}
|
||||||
{{::ticket.street}}
|
{{::ticket.street}}
|
||||||
{{::ticket.postalCode}}
|
{{::ticket.postalCode}}
|
||||||
{{::ticket.city}}">
|
{{::ticket.city}}">
|
||||||
{{::ticket.nickname}}
|
{{::ticket.nickname}}
|
||||||
{{::ticket.name}}
|
{{::ticket.name}}
|
||||||
{{::ticket.street}}
|
{{::ticket.street}}
|
||||||
{{::ticket.postalCode}}
|
{{::ticket.postalCode}}
|
||||||
{{::ticket.city}}
|
{{::ticket.city}}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td
|
<td
|
||||||
ng-if="!$ctrl.transfer.lastActiveTickets.length"
|
ng-if="!$ctrl.transfer.lastActiveTickets.length"
|
||||||
class="empty-rows"
|
class="empty-rows"
|
||||||
colspan="4"
|
colspan="4"
|
||||||
translate>
|
translate>
|
||||||
|
@ -502,4 +519,4 @@
|
||||||
vn-acl-action="remove">
|
vn-acl-action="remove">
|
||||||
Refund
|
Refund
|
||||||
</vn-item>
|
</vn-item>
|
||||||
</vn-menu>
|
</vn-menu>
|
||||||
|
|
|
@ -13,9 +13,9 @@ New ticket: Nuevo ticket
|
||||||
Edit price: Editar precio
|
Edit price: Editar precio
|
||||||
You are going to delete lines of the ticket: Vas a eliminar lineas del ticket
|
You are going to delete lines of the ticket: Vas a eliminar lineas del ticket
|
||||||
This ticket will be removed from current route! Continue anyway?: ¡Se eliminará el ticket de la ruta actual! ¿Continuar de todas formas?
|
This ticket will be removed from current route! Continue anyway?: ¡Se eliminará el ticket de la ruta actual! ¿Continuar de todas formas?
|
||||||
You have to allow pop-ups in your web browser to use this functionality:
|
You have to allow pop-ups in your web browser to use this functionality:
|
||||||
Debes permitir los pop-pups en tu navegador para que esta herramienta funcione correctamente
|
Debes permitir los pop-pups en tu navegador para que esta herramienta funcione correctamente
|
||||||
Disc: Dto
|
Disc: Dto
|
||||||
Available: Disponible
|
Available: Disponible
|
||||||
What is the day of receipt of the ticket?: ¿Cual es el día de preparación del pedido?
|
What is the day of receipt of the ticket?: ¿Cual es el día de preparación del pedido?
|
||||||
Add claim: Crear reclamación
|
Add claim: Crear reclamación
|
||||||
|
@ -39,3 +39,4 @@ Packaging: Encajado
|
||||||
Refund: Abono
|
Refund: Abono
|
||||||
Promotion mana: Maná promoción
|
Promotion mana: Maná promoción
|
||||||
Claim mana: Maná reclamación
|
Claim mana: Maná reclamación
|
||||||
|
History: Historial
|
||||||
|
|
Loading…
Reference in New Issue