Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 6276-createNewWarehouse
gitea/salix/pipeline/head There was a failure building this commit Details

This commit is contained in:
Jorge Penadés 2024-01-04 15:07:33 +01:00
commit 7a64b57a2a
93 changed files with 375 additions and 190 deletions

View File

@ -16,6 +16,7 @@
},
"cSpell.words": [
"salix",
"fdescribe"
"fdescribe",
"Loggable"
]
}

View File

@ -68,7 +68,7 @@ module.exports = Self => {
userToUpdate.hasGrant = hasGrant;
if (roleFk) {
const role = await models.Role.findById(roleFk, {fields: ['name']}, myOptions);
const role = await models.VnRole.findById(roleFk, {fields: ['name']}, myOptions);
const hasRole = await Self.hasRole(userId, role.name, myOptions);
if (!hasRole)

View File

@ -70,7 +70,7 @@ describe('VnUser privileges()', () => {
const tx = await models.VnUser.beginTransaction({});
const options = {transaction: tx};
const agency = await models.Role.findOne({
const agency = await models.VnRole.findOne({
where: {
name: 'agency'
}

View File

@ -145,9 +145,6 @@
"Warehouse": {
"dataSource": "vn"
},
"VnUser": {
"dataSource": "vn"
},
"OsTicket": {
"dataSource": "osticket"
},
@ -162,6 +159,12 @@
},
"ViaexpressConfig": {
"dataSource": "vn"
},
"VnUser": {
"dataSource": "vn"
},
"VnRole": {
"dataSource": "vn"
}
}

View File

@ -29,12 +29,12 @@
"relations": {
"readRole": {
"type": "belongsTo",
"model": "Role",
"model": "VnRole",
"foreignKey": "readRoleFk"
},
"writeRole": {
"type": "belongsTo",
"model": "Role",
"model": "VnRole",
"foreignKey": "writeRoleFk"
}
},

View File

@ -46,12 +46,12 @@
},
"readRole": {
"type": "belongsTo",
"model": "Role",
"model": "VnRole",
"foreignKey": "readRoleFk"
},
"writeRole": {
"type": "belongsTo",
"model": "Role",
"model": "VnRole",
"foreignKey": "writeRoleFk"
}
},
@ -64,4 +64,3 @@
}
]
}

View File

@ -24,7 +24,7 @@
},
"role": {
"type": "belongsTo",
"model": "Role",
"model": "VnRole",
"foreignKey": "roleFk"
}
}

13
back/models/vn-role.json Normal file
View File

@ -0,0 +1,13 @@
{
"name": "VnRole",
"base": "Role",
"validateUpsert": true,
"options": {
"mysql": {
"table": "account.role"
}
},
"mixins": {
"Loggable": true
}
}

View File

@ -7,6 +7,9 @@
"table": "account.user"
}
},
"mixins": {
"Loggable": true
},
"resetPasswordTokenTTL": "604800",
"properties": {
"id": {
@ -63,7 +66,7 @@
"relations": {
"role": {
"type": "belongsTo",
"model": "Role",
"model": "VnRole",
"foreignKey": "roleFk"
},
"roles": {

View File

@ -0,0 +1,6 @@
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId) VALUES
('VnRole','*','READ','ALLOW','ROLE','employee'),
('VnRole','*','WRITE','ALLOW','ROLE','it');
DELETE FROM`salix`.`ACL` WHERE model='Role';

View File

@ -23,7 +23,6 @@ export function directive($translate, $window) {
let rule = $attrs.rule.split('.');
let modelName = rule.shift();
let fieldName = rule.shift();
let split = $attrs.ngModel.split('.');
if (!fieldName) fieldName = split.pop() || null;
if (!modelName) modelName = firstUpper(split.pop() || '');

View File

@ -0,0 +1,12 @@
const LoopBackContext = require('loopback-context');
async function handleObserve(ctx) {
ctx.options.httpCtx = LoopBackContext.getCurrentContext();
}
module.exports = function(Self) {
let Mixin = {
'before save': handleObserve,
'before delete': handleObserve,
};
for (const [listener, handler] of Object.entries(Mixin))
Self.observe(listener, handler);
};

View File

@ -1,15 +0,0 @@
const LoopBackContext = require('loopback-context');
module.exports = function(Self) {
Self.setup = function() {
Self.super_.setup.call(this);
};
Self.observe('before save', async function(ctx) {
ctx.options.httpCtx = LoopBackContext.getCurrentContext();
});
Self.observe('before delete', async function(ctx) {
ctx.options.httpCtx = LoopBackContext.getCurrentContext();
});
};

View File

@ -1,5 +0,0 @@
{
"name": "Loggable",
"base": "VnModel",
"validateUpsert": true
}

View File

@ -25,20 +25,19 @@
"FieldAcl": {
"dataSource": "vn"
},
"Role": {
"dataSource": "vn",
"options": {
"mysql": {
"table": "salix.Role"
}
}
},
"RoleMapping": {
"dataSource": "vn",
"options": {
"mysql": {
"table": "salix.RoleMapping"
}
},
"relations": {
"role": {
"type": "belongsTo",
"model": "VnRole",
"foreignKey": "roleId"
}
}
},
"Schema": {

View File

@ -239,7 +239,7 @@ module.exports = Self => {
// Prepare data
let roles = await $.Role.find({
let roles = await $.VnRole.find({
fields: ['id', 'name', 'description']
});
let roleRoles = await $.RoleRole.find({

View File

@ -15,12 +15,12 @@
"relations": {
"owner": {
"type": "belongsTo",
"model": "Role",
"model": "VnRole",
"foreignKey": "role"
},
"inherits": {
"type": "belongsTo",
"model": "Role",
"model": "VnRole",
"foreignKey": "inheritsFrom"
}
}

View File

@ -14,12 +14,12 @@
"relations": {
"owner": {
"type": "belongsTo",
"model": "Role",
"model": "VnRole",
"foreignKey": "role"
},
"inherits": {
"type": "belongsTo",
"model": "Role",
"model": "VnRole",
"foreignKey": "inheritsFrom"
}
}

View File

@ -15,7 +15,7 @@
<vn-autocomplete
label="Role"
ng-model="$ctrl.acl.principalId"
url="Roles"
url="VnRoles"
id-field="name"
value-field="name"
vn-focus>

View File

@ -4,7 +4,7 @@
<vn-autocomplete
label="Role"
ng-model="filter.principalId"
url="Roles"
url="VnRoles"
value-field="name">
</vn-autocomplete>
<vn-autocomplete

View File

@ -30,7 +30,7 @@
<vn-autocomplete
label="Role"
ng-model="$ctrl.user.roleFk"
url="Roles"
url="VnRoles"
rule="VnUser">
</vn-autocomplete>
<vn-textfield

View File

@ -22,7 +22,7 @@
<vn-autocomplete
label="Role"
ng-model="$ctrl.user.roleFk"
url="Roles">
url="VnRoles">
</vn-autocomplete>
</vn-vertical>
</vn-card>

View File

@ -1,25 +1,27 @@
<vn-watcher
vn-id="watcher"
url="Roles"
url="VnRoles"
data="$ctrl.role"
form="form">
</vn-watcher>
<form
name="form"
ng-submit="watcher.submit()"
class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-vertical>
<vn-textfield
label="Name"
ng-model="$ctrl.role.name"
rule
rule="VnRole.name"
vn-focus>
</vn-textfield>
<vn-textfield
label="Description"
ng-model="$ctrl.role.description"
rule>
rule="VnRole.description"
>
</vn-textfield>
</vn-vertical>
</vn-card>

View File

@ -3,7 +3,7 @@ import ModuleCard from 'salix/components/module-card';
class Controller extends ModuleCard {
reload() {
this.$http.get(`Roles/${this.$params.id}`)
this.$http.get(`VnRoles/${this.$params.id}`)
.then(res => this.role = res.data);
}
}

View File

@ -1,6 +1,6 @@
import './index';
describe('component vnRoleCard', () => {
fdescribe('component vnRoleCard', () => {
let controller;
let $httpBackend;
@ -15,7 +15,7 @@ describe('component vnRoleCard', () => {
it('should reload the controller data', () => {
controller.$params.id = 1;
$httpBackend.expectGET('Roles/1').respond('foo');
$httpBackend.expectGET('VnRoles/1').respond('foo');
controller.reload();
$httpBackend.flush();

View File

@ -1,6 +1,6 @@
<vn-watcher
vn-id="watcher"
url="Roles"
url="VnRoles"
data="$ctrl.role"
insert-mode="true"
form="form">
@ -14,13 +14,13 @@
<vn-textfield
label="Name"
ng-model="$ctrl.role.name"
rule
rule="VnRole.name"
vn-focus>
</vn-textfield>
<vn-textfield
label="Description"
ng-model="$ctrl.role.description"
rule>
rule="VnRole.description">
</vn-textfield>
</vn-vertical>
</vn-card>

View File

@ -11,7 +11,7 @@ class Controller extends Descriptor {
}
onDelete() {
return this.$http.delete(`Roles/${this.id}`)
return this.$http.delete(`VnRoles/${this.id}`)
.then(() => this.$state.go('account.role'))
.then(() => this.vnApp.showSuccess(this.$t('Role removed')));
}

View File

@ -1,6 +1,6 @@
import './index';
describe('component vnRoleDescriptor', () => {
fdescribe('component vnRoleDescriptor', () => {
let controller;
let $httpBackend;
@ -18,7 +18,7 @@ describe('component vnRoleDescriptor', () => {
controller.$state.go = jest.fn();
jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expectDELETE('Roles/1').respond();
$httpBackend.expectDELETE('VnRoles/1').respond();
controller.onDelete();
$httpBackend.flush();

View File

@ -1,6 +1,6 @@
<vn-crud-model
vn-id="model"
url="Roles"
url="VnRoles"
filter="::$ctrl.filter"
limit="20">
</vn-crud-model>

View File

@ -40,7 +40,7 @@
<vn-autocomplete
label="Role"
ng-model="$ctrl.addData.inheritsFrom"
url="Roles"
url="VnRoles"
vn-focus>
</vn-autocomplete>
</tpl-body>

View File

@ -6,7 +6,7 @@ class Controller extends Component {
this._role = value;
this.$.summary = null;
if (!value) return;
this.$http.get(`Roles/${value.id}`)
this.$http.get(`VnRoles/${value.id}`)
.then(res => this.$.summary = res.data);
}

View File

@ -19,7 +19,7 @@
vn-one
label="Role"
ng-model="filter.roleFk"
url="Roles"
url="VnRoles"
value-field="id"
show-field="name">
</vn-autocomplete>

View File

@ -1,6 +1,9 @@
{
"name": "ClaimBeginning",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "claimBeginning"

View File

@ -1,6 +1,9 @@
{
"name": "ClaimDevelopment",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "claimDevelopment"

View File

@ -1,6 +1,9 @@
{
"name": "ClaimDms",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "claimDms"

View File

@ -1,6 +1,9 @@
{
"name": "ClaimEnd",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "claimEnd"

View File

@ -1,6 +1,9 @@
{
"name": "ClaimObservation",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "claimObservation"

View File

@ -1,6 +1,9 @@
{
"name": "ClaimState",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "claimState"
@ -32,7 +35,7 @@
"relations": {
"writeRole": {
"type": "belongsTo",
"model": "Role",
"model": "VnRole",
"foreignKey": "roleFk"
}
},

View File

@ -1,6 +1,9 @@
{
"name": "Claim",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "claim"

View File

@ -1,7 +1,10 @@
{
"name": "Address",
"description": "Client addresses",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "address"

View File

@ -1,7 +1,10 @@
{
"name": "ClientContact",
"description": "Client phone contacts",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "clientContact"

View File

@ -1,6 +1,9 @@
{
"name": "ClientDms",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "clientDms"

View File

@ -1,6 +1,9 @@
{
"name": "ClientInforma",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"log": {
"model":"ClientLog",
"relation": "client",

View File

@ -1,7 +1,10 @@
{
"name": "ClientObservation",
"description": "Client notes",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "clientObservation"

View File

@ -1,6 +1,9 @@
{
"name": "ClientSample",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "clientSample"

View File

@ -1,6 +1,9 @@
{
"name": "Client",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "client"

View File

@ -1,6 +1,9 @@
{
"name": "Greuge",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "greuge"

View File

@ -1,6 +1,9 @@
{
"name": "Recovery",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "recovery"

View File

@ -19,7 +19,7 @@
"relations": {
"role": {
"type": "belongsTo",
"model": "Role",
"model": "VnRole",
"foreignKey": "roleFk"
}
}

View File

@ -1,6 +1,9 @@
{
"name": "Buy",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "buy"

View File

@ -1,6 +1,9 @@
{
"name": "EntryObservation",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "entryObservation"

View File

@ -1,6 +1,9 @@
{
"name": "Entry",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "entry"

View File

@ -1,6 +1,9 @@
{
"name": "InvoiceInTax",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "invoiceInTax"

View File

@ -1,6 +1,9 @@
{
"name": "InvoiceIn",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "invoiceIn"

View File

@ -85,7 +85,7 @@ module.exports = Self => {
throw new UserError(`A ticket with an amount of zero can't be invoiced`);
// Validates ticket nagative base
const hasNegativeBase = await getNegativeBase(ticketId, myOptions);
const hasNegativeBase = await getNegativeBase(maxShipped, clientId, companyId, myOptions);
if (hasNegativeBase && company.code == 'VNL')
throw new UserError(`A ticket with a negative base can't be invoiced`);
} else {
@ -162,10 +162,13 @@ module.exports = Self => {
return result.invoiceable;
}
async function getNegativeBase(ticketId, options) {
async function getNegativeBase(maxShipped, clientId, companyId, options) {
const models = Self.app.models;
const query = 'SELECT vn.hasSomeNegativeBase(?) AS base';
const [result] = await models.InvoiceOut.rawSql(query, [ticketId], options);
await models.InvoiceOut.rawSql('CALL invoiceOut_exportationFromClient(?,?,?)',
[maxShipped, clientId, companyId], options
);
const query = 'SELECT vn.hasAnyNegativeBase() AS base';
const [result] = await models.InvoiceOut.rawSql(query, [], options);
return result.base;
}

View File

@ -1,6 +1,9 @@
{
"name": "ItemBarcode",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "itemBarcode"

View File

@ -1,6 +1,9 @@
{
"name": "ItemBotanical",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "itemBotanical"

View File

@ -1,6 +1,9 @@
{
"name": "ItemShelving",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "itemShelving"

View File

@ -1,6 +1,9 @@
{
"name": "ItemTag",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "itemTag"

View File

@ -1,6 +1,9 @@
{
"name": "ItemTaxCountry",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "itemTaxCountry"

View File

@ -1,6 +1,9 @@
{
"name": "Item",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "item"

View File

@ -1,6 +1,9 @@
{
"name": "Route",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "route"

View File

@ -1,6 +1,9 @@
{
"name": "Shelving",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "shelving"

View File

@ -1,6 +1,9 @@
{
"name": "SupplierAccount",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "supplierAccount"

View File

@ -1,7 +1,10 @@
{
"name": "SupplierAddress",
"description": "Supplier addresses",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "supplierAddress"

View File

@ -1,6 +1,9 @@
{
"name": "SupplierContact",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "supplierContact"

View File

@ -1,6 +1,9 @@
{
"name": "Supplier",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "supplier"

View File

@ -102,7 +102,7 @@ describe('sale canEdit()', () => {
try {
const options = {transaction: tx};
const role = await models.Role.findOne({
const role = await models.VnRole.findOne({
where: {
name: roleEnabled.principalId
}
@ -159,7 +159,7 @@ describe('sale canEdit()', () => {
try {
const options = {transaction: tx};
const role = await models.Role.findOne({
const role = await models.VnRole.findOne({
where: {
name: roleEnabled.principalId
}

View File

@ -1,6 +1,9 @@
{
"name": "Expedition",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "expedition"

View File

@ -1,6 +1,9 @@
{
"name": "Sale",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "sale"

View File

@ -1,6 +1,9 @@
{
"name": "TicketDms",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "ticketDms"

View File

@ -1,6 +1,9 @@
{
"name": "TicketObservation",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "ticketObservation"

View File

@ -1,6 +1,9 @@
{
"name": "TicketPackaging",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "ticketPackaging"

View File

@ -1,6 +1,9 @@
{
"name": "TicketRefund",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "ticketRefund"

View File

@ -1,6 +1,9 @@
{
"name": "TicketRequest",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "ticketRequest"

View File

@ -1,6 +1,9 @@
{
"name": "TicketService",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "ticketService"

View File

@ -1,6 +1,9 @@
{
"name": "TicketTracking",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "ticketTracking"

View File

@ -1,6 +1,9 @@
{
"name": "TicketWeekly",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "ticketWeekly"

View File

@ -1,6 +1,9 @@
{
"name": "Ticket",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "ticket"

View File

@ -1,6 +1,9 @@
{
"name": "TravelThermograph",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "travelThermograph"

View File

@ -1,6 +1,9 @@
{
"name": "Travel",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "travel"

View File

@ -3,7 +3,7 @@ const app = require('vn-loopback/server/server');
describe('Worker activeWithInheritedRole', () => {
let allRolesCount;
beforeAll(async() => {
allRolesCount = await app.models.Role.count();
allRolesCount = await app.models.VnRole.count();
});
it('should return the workers with an inherited role of salesPerson', async() => {

View File

@ -1,6 +1,9 @@
{
"name": "DeviceProductionUser",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"log": {
"model": "DeviceProductionLog",
"relation": "deviceProduction"

View File

@ -1,6 +1,9 @@
{
"name": "DeviceProduction",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"log": {
"model": "DeviceProductionLog"
},

View File

@ -1,6 +1,9 @@
{
"name": "WorkerDms",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "workerDocument"

View File

@ -1,7 +1,10 @@
{
"name": "Worker",
"description": "Company employees",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "worker"

View File

@ -1,6 +1,9 @@
{
"name": "ZoneEvent",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "zoneEvent"

View File

@ -1,6 +1,9 @@
{
"name": "ZoneExclusion",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "zoneExclusion"

View File

@ -1,6 +1,9 @@
{
"name": "ZoneIncluded",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "zoneIncluded"

View File

@ -1,6 +1,9 @@
{
"name": "ZoneWarehouse",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "zoneWarehouse"

View File

@ -1,6 +1,9 @@
{
"name": "Zone",
"base": "Loggable",
"base": "VnModel",
"mixins": {
"Loggable": true
},
"options": {
"mysql": {
"table": "zone"