3092-module_transactions #740

Merged
joan merged 41 commits from 3092-module_transactions into dev 2021-10-18 07:42:24 +00:00
14 changed files with 323 additions and 93 deletions
Showing only changes of commit b9460723f8 - Show all commits

View File

@ -19,28 +19,42 @@
ng-if="$ctrl.displayControls"> ng-if="$ctrl.displayControls">
</vn-button> </vn-button>
</div> </div>
<div class="weekdays"> <div id="days-header" ng-class="{'hide-weeks': $ctrl.hideWeeks}">
<section <div class="week-numbers" ng-if="!$ctrl.hideWeeks"></div>
ng-repeat="day in ::$ctrl.weekDays" <div class="weekdays">
translate-attr="::{title: day.name}" <section
ng-click="$ctrl.selectWeekDay($event, day.index)"> ng-repeat="day in ::$ctrl.weekDays"
<span>{{::day.localeChar}}</span> translate-attr="::{title: day.name}"
</section> ng-click="$ctrl.selectWeekDay($event, day.index)">
<span>{{::day.localeChar}}</span>
</section>
</div>
</div> </div>
<div
class="days" <div id="days-container" ng-class="{'hide-weeks': $ctrl.hideWeeks}">
ng-class="{'hide-contiguous': $ctrl.hideContiguous}"> <div class="weeks" ng-if="!$ctrl.hideWeeks">
<section <section ng-repeat="week in $ctrl.weekNumbers"
ng-repeat="day in $ctrl.days" class="day">
class="day" <div class="day-number">
ng-class="::$ctrl.getDayClasses(day)" {{::week}}
vn-repeat-last </div>
on-last="$ctrl.repeatLast()"> </section>
<div </div>
class="day-number" <div
ng-click="$ctrl.select($event, day)"> class="days"
{{::day | date: 'd'}} ng-class="{'hide-contiguous': $ctrl.hideContiguous}">
</div> <section
</section> ng-repeat="day in $ctrl.days"
class="day"
ng-class="::$ctrl.getDayClasses(day)"
vn-repeat-last
on-last="$ctrl.repeatLast()">
<div
class="day-number"
ng-click="$ctrl.select($event, day)">
{{::day | date: 'd'}}
</div>
</section>
</div>
</div> </div>
</div> </div>

View File

@ -12,11 +12,12 @@ import './style.scss';
* @event move Emitted when month changes * @event move Emitted when month changes
*/ */
export default class Calendar extends FormInput { export default class Calendar extends FormInput {
constructor($element, $scope, vnWeekDays) { constructor($element, $scope, vnWeekDays, moment) {
super($element, $scope); super($element, $scope);
this.weekDays = vnWeekDays.locales; this.weekDays = vnWeekDays.locales;
this.defaultDate = new Date(); this.defaultDate = new Date();
this.displayControls = true; this.displayControls = true;
this.moment = moment;
} }
/** /**
@ -54,15 +55,23 @@ export default class Calendar extends FormInput {
); );
} }
lastDay() {
return new Date(
this.defaultDate.getFullYear(),
this.defaultDate.getMonth() + 1,
0
).getDate();
}
/** /**
* Repaints the calendar. * Repaints the calendar.
*/ */
repaint() { repaint() {
const firstWeekday = this.firstDay(this.defaultDate).getDay() - 1; const firstWeekday = this.firstDay(this.defaultDate).getDay() - 1;
let weekdayOffset = firstWeekday >= 0 ? firstWeekday : 6; this.weekdayOffset = firstWeekday >= 0 ? firstWeekday : 6;
let dayIndex = new Date(this.defaultDate.getTime()); let dayIndex = new Date(this.defaultDate.getTime());
dayIndex.setDate(1 - weekdayOffset); dayIndex.setDate(1 - this.weekdayOffset);
this.days = []; this.days = [];
@ -70,27 +79,55 @@ export default class Calendar extends FormInput {
this.days.push(new Date(dayIndex.getTime())); this.days.push(new Date(dayIndex.getTime()));
dayIndex.setDate(dayIndex.getDate() + 1); dayIndex.setDate(dayIndex.getDate() + 1);
} }
this.getWeekdays();
}
getWeekdays() {
if (!this.moment) return;
const totalSlots = this.lastDay() + this.weekdayOffset;
const weeks = Math.ceil(totalSlots / 7);
const dated = this.moment(this.defaultDate);
const firstWeekNumber = dated.set('date', 1).isoWeek();
const weekNumbers = [];
for (let w = 0; w < weeks; w++) {
let weekNumber = firstWeekNumber;
if (dated.get('month') == 0 && firstWeekNumber > 1 && w > 0)
weekNumber = 0;
weekNumbers.push(weekNumber + w);
}
this.weekNumbers = weekNumbers;
} }
/** /**
* Gets CSS classes to apply to the specified day. * Gets CSS classes to apply to the specified day.
* *
* @param {Date} day The day * @param {Date} date The date
* @return {Object} The CSS classes to apply * @return {Object} The CSS classes to apply
*/ */
getDayClasses(day) { getDayClasses(date) {
let wday = day.getDay(); let day = date.getDate();
let month = day.getMonth(); let wday = date.getDay();
let month = date.getMonth();
const currentDay = new Date().getDate();
const currentMonth = new Date().getMonth();
let classes = { let classes = {
today: day === currentDay && month === currentMonth,
weekend: wday === 6 || wday === 0, weekend: wday === 6 || wday === 0,
previous: month < this.month, previous: month < this.month,
current: month == this.month, current: month == this.month,
next: month > this.month, next: month > this.month,
event: this.hasEvents({$day: day}) event: this.hasEvents({$day: date})
}; };
let userClass = this.getClass({$day: day}); let userClass = this.getClass({$day: date});
if (userClass) classes[userClass] = true; if (userClass) classes[userClass] = true;
return classes; return classes;
@ -181,7 +218,7 @@ export default class Calendar extends FormInput {
} }
} }
} }
Calendar.$inject = ['$element', '$scope', 'vnWeekDays']; Calendar.$inject = ['$element', '$scope', 'vnWeekDays', 'moment'];
ngModule.vnComponent('vnCalendar', { ngModule.vnComponent('vnCalendar', {
template: require('./index.html'), template: require('./index.html'),
@ -193,6 +230,7 @@ ngModule.vnComponent('vnCalendar', {
formatDay: '&?', formatDay: '&?',
displayControls: '<?', displayControls: '<?',
hideYear: '<?', hideYear: '<?',
hideContiguous: '<?' hideContiguous: '<?',
hideWeeks: '<?'
} }
}); });

View File

@ -19,7 +19,14 @@
color: inherit; color: inherit;
} }
} }
& > .weekdays { & #days-header {
flex-direction: row;
display: flex
}
& #days-header > .week-numbers {
width: 10%
}
& #days-header > .weekdays {
display: flex; display: flex;
color: $color-font-secondary; color: $color-font-secondary;
margin-bottom: 8px; margin-bottom: 8px;
@ -27,17 +34,49 @@
font-weight: bold; font-weight: bold;
font-size: .8rem; font-size: .8rem;
text-align: center; text-align: center;
width: 90%;
& > section { & > section {
width: 14.28%; width: 14.28%;
cursor: pointer; cursor: pointer;
} }
} }
& > .days { & #days-header.hide-weeks {
& > .weekdays {
width: 100%
}
}
& > #days-container {
flex-direction: row;
display: flex
}
& > #days-container > .weeks {
display: flex; display: flex;
flex-direction: column;
color: $color-font-secondary;
font-weight: bold;
font-size: .8rem;
width: 10%;
& > .day {
height: 40px;
display: flex;
justify-content: center;
align-items: center;
}
}
& #days-container.hide-weeks {
& > .days {
width: 100%
}
}
#days-container > .days {
display: flex;
flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
width: 90%;
& > .day { & > .day {
width: 14.28%; width: 14.28%;
@ -46,6 +85,17 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
&.today {
color: $color-font-bg;
& > .day-number {
border: 2px solid $color-font-link;
&:hover {
background-color: lighten($color-font-link, 20%);
opacity: .8
}
}
}
&.weekend { &.weekend {
color: $color-font-secondary; color: $color-font-secondary;
} }

View File

@ -9,13 +9,15 @@ import 'angular-translate-loader-partial';
import '@uirouter/angularjs'; import '@uirouter/angularjs';
import 'mg-crud'; import 'mg-crud';
import 'oclazyload'; import 'oclazyload';
import 'angular-moment';
export const ngDeps = [ export const ngDeps = [
'ngAnimate', 'ngAnimate',
'pascalprecht.translate', 'pascalprecht.translate',
'ui.router', 'ui.router',
'mgCrud', 'mgCrud',
'oc.lazyLoad' 'oc.lazyLoad',
'angularMoment'
]; ];
import * as validator from 'validator'; import * as validator from 'validator';

View File

@ -12,6 +12,7 @@
"@uirouter/angularjs": "^1.0.20", "@uirouter/angularjs": "^1.0.20",
"angular": "^1.7.5", "angular": "^1.7.5",
"angular-animate": "^1.7.8", "angular-animate": "^1.7.8",
"angular-moment": "^1.3.0",
"angular-translate": "^2.18.1", "angular-translate": "^2.18.1",
"angular-translate-loader-partial": "^2.18.1", "angular-translate-loader-partial": "^2.18.1",
"croppie": "^2.6.5", "croppie": "^2.6.5",
@ -51,6 +52,17 @@
"resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.8.2.tgz", "resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.8.2.tgz",
"integrity": "sha512-Jbr9+grNMs9Kj57xuBU3Ju3NOPAjS1+g2UAwwDv7su1lt0/PLDy+9zEwDiu8C8xJceoTbmBNKiWGPJGBdCQLlA==" "integrity": "sha512-Jbr9+grNMs9Kj57xuBU3Ju3NOPAjS1+g2UAwwDv7su1lt0/PLDy+9zEwDiu8C8xJceoTbmBNKiWGPJGBdCQLlA=="
}, },
"node_modules/angular-moment": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/angular-moment/-/angular-moment-1.3.0.tgz",
"integrity": "sha512-KG8rvO9MoaBLwtGnxTeUveSyNtrL+RNgGl1zqWN36+HDCCVGk2DGWOzqKWB6o+eTTbO3Opn4hupWKIElc8XETA==",
"dependencies": {
"moment": ">=2.8.0 <3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/angular-translate": { "node_modules/angular-translate": {
"version": "2.18.4", "version": "2.18.4",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.4.tgz", "resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.4.tgz",
@ -115,6 +127,14 @@
"angular": "^1.6.1" "angular": "^1.6.1"
} }
}, },
"node_modules/moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
"engines": {
"node": "*"
}
},
"node_modules/oclazyload": { "node_modules/oclazyload": {
"version": "0.6.3", "version": "0.6.3",
"resolved": "https://registry.npmjs.org/oclazyload/-/oclazyload-0.6.3.tgz", "resolved": "https://registry.npmjs.org/oclazyload/-/oclazyload-0.6.3.tgz",
@ -182,6 +202,14 @@
"resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.8.2.tgz", "resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.8.2.tgz",
"integrity": "sha512-Jbr9+grNMs9Kj57xuBU3Ju3NOPAjS1+g2UAwwDv7su1lt0/PLDy+9zEwDiu8C8xJceoTbmBNKiWGPJGBdCQLlA==" "integrity": "sha512-Jbr9+grNMs9Kj57xuBU3Ju3NOPAjS1+g2UAwwDv7su1lt0/PLDy+9zEwDiu8C8xJceoTbmBNKiWGPJGBdCQLlA=="
}, },
"angular-moment": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/angular-moment/-/angular-moment-1.3.0.tgz",
"integrity": "sha512-KG8rvO9MoaBLwtGnxTeUveSyNtrL+RNgGl1zqWN36+HDCCVGk2DGWOzqKWB6o+eTTbO3Opn4hupWKIElc8XETA==",
"requires": {
"moment": ">=2.8.0 <3.0.0"
}
},
"angular-translate": { "angular-translate": {
"version": "2.18.4", "version": "2.18.4",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.4.tgz", "resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.4.tgz",
@ -233,6 +261,11 @@
"angular": "^1.6.1" "angular": "^1.6.1"
} }
}, },
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"oclazyload": { "oclazyload": {
"version": "0.6.3", "version": "0.6.3",
"resolved": "https://registry.npmjs.org/oclazyload/-/oclazyload-0.6.3.tgz", "resolved": "https://registry.npmjs.org/oclazyload/-/oclazyload-0.6.3.tgz",

View File

@ -12,6 +12,7 @@
"@uirouter/angularjs": "^1.0.20", "@uirouter/angularjs": "^1.0.20",
"angular": "^1.7.5", "angular": "^1.7.5",
"angular-animate": "^1.7.8", "angular-animate": "^1.7.8",
"angular-moment": "^1.3.0",
"angular-translate": "^2.18.1", "angular-translate": "^2.18.1",
"angular-translate-loader-partial": "^2.18.1", "angular-translate-loader-partial": "^2.18.1",
"croppie": "^2.6.5", "croppie": "^2.6.5",

View File

@ -78,6 +78,11 @@
</vn-avatar> </vn-avatar>
<span translate>Festive</span> <span translate>Festive</span>
</vn-chip> </vn-chip>
<vn-chip>
<vn-avatar class="today">
</vn-avatar>
<span translate>Current day</span>
</vn-chip>
</div> </div>
</div> </div>
</vn-side-menu> </vn-side-menu>

View File

@ -8,3 +8,4 @@ days: días
Choose an absence type from the right menu: Elige un tipo de ausencia desde el menú de la derecha Choose an absence type from the right menu: Elige un tipo de ausencia desde el menú de la derecha
To start adding absences, click an absence type from the right menu and then on the day you want to add an absence: Para empezar a añadir ausencias, haz clic en un tipo de ausencia desde el menu de la derecha y después en el día que quieres añadir la ausencia To start adding absences, click an absence type from the right menu and then on the day you want to add an absence: Para empezar a añadir ausencias, haz clic en un tipo de ausencia desde el menu de la derecha y después en el día que quieres añadir la ausencia
You can just add absences within the current year: Solo puedes añadir ausencias dentro del año actual You can just add absences within the current year: Solo puedes añadir ausencias dentro del año actual
Current day: Día actual

View File

@ -42,11 +42,19 @@ vn-worker-calendar {
border-bottom: 1px solid rgba(0, 0, 0, 0.3); border-bottom: 1px solid rgba(0, 0, 0, 0.3);
} }
.festive { vn-avatar.festive,
background-color:white; vn-avatar.today {
border: 2px solid $color-alert; background-color: $color-font-dark;
width: 24px; width: 24px;
min-width: 24px; min-width: 24px;
height: 24px height: 24px
} }
vn-avatar.festive {
border: 2px solid $color-alert
}
vn-avatar.today {
border: 2px solid $color-font-link
}
} }

View File

@ -118,20 +118,20 @@
</table> </table>
<!-- End of sales block --> <!-- End of sales block -->
<div class="columns"> <div class="columns vn-mb-ml">
<!-- Services block--> <!-- Services block-->
<div class="size100 no-page-break" v-if="services.length > 0"> <div class="size100 no-page-break" v-if="services.length > 0">
<h2>{{$t('services')}}</h2> <h2>{{$t('services.title')}}</h2>
<table class="column-oriented"> <table class="column-oriented">
<thead> <thead>
<tr> <tr>
<th width="5%"></th> <th width="5%"></th>
<th class="number">{{$t('quantity')}}</th> <th class="number">{{$t('services.theader.quantity')}}</th>
<th width="50%">{{$t('concept')}}</th> <th width="50%">{{$t('services.theader.concept')}}</th>
<th class="number">{{$t('price')}}</th> <th class="number">{{$t('services.theader.price')}}</th>
<th class="centered" width="5%"></th> <th class="centered" width="5%"></th>
<th class="centered">{{$t('vat')}}</th> <th class="centered">{{$t('services.theader.vat')}}</th>
<th class="number">{{$t('amount')}}</th> <th class="number">{{$t('services.theader.amount')}}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -148,25 +148,26 @@
<tfoot> <tfoot>
<tr> <tr>
<td colspan="6" class="font bold"> <td colspan="6" class="font bold">
<span class="pull-right">{{$t('subtotal')}}</span> <span class="pull-right">{{$t('services.tfoot.subtotal')}}</span>
</td> </td>
<td class="number">{{serviceTotal | currency('EUR', $i18n.locale)}}</td> <td class="number">{{serviceTotal | currency('EUR', $i18n.locale)}}</td>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
<span class="font gray">* {{ $t('services.warning') }}</span>
</div> </div>
<!-- End of services block --> <!-- End of services block -->
</div> </div>
<div class="columns"> <div class="columns">
<!-- Packages block --> <!-- Packages block -->
<div id="packagings" class="size100 no-page-break" v-if="packagings.length > 0"> <div id="packagings" class="size100 no-page-break" v-if="packagings.length > 0">
<h2>{{$t('packagings')}}</h2> <h2>{{$t('packagings.title')}}</h2>
<table class="column-oriented"> <table class="column-oriented">
<thead> <thead>
<tr> <tr>
<th>{{$t('reference')}}</th> <th>{{$t('packagings.theader.reference')}}</th>
<th class="number">{{$t('quantity')}}</th> <th class="number">{{$t('packagings.theader.quantity')}}</th>
<th wihth="75%">{{$t('concept')}}</th> <th wihth="75%">{{$t('packagings.theader.concept')}}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -183,21 +184,18 @@
<div class="columns vn-mt-xl"> <div class="columns vn-mt-xl">
<!-- Taxes block --> <!-- Taxes block -->
<div id="taxes" class="size50 pull-right no-page-break" v-if="taxes"> <div id="taxes" class="size50 pull-right no-page-break" v-if="taxes">
<!-- <h2>{{$t('taxBreakdown')}}</h2> -->
<table class="column-oriented"> <table class="column-oriented">
<thead> <thead>
<tr> <tr>
<th colspan="4">{{$t('taxBreakdown')}}</th> <th colspan="4">{{$t('taxes.title')}}</th>
</tr> </tr>
</thead> </thead>
<thead class="light"> <thead class="light">
<tr> <tr>
<th width="45%">{{$t('type')}}</th> <th width="45%">{{$t('taxes.theader.type')}}</th>
<th width="25%" class="number"> <th width="25%" class="number">{{$t('taxes.theader.taxBase')}}</th>
{{$t('taxBase')}} <th>{{$t('taxes.theader.tax')}}</th>
</th> <th class="number">{{$t('taxes.theader.fee')}}</th>
<th>{{$t('tax')}}</th>
<th class="number">{{$t('fee')}}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -12,17 +12,37 @@ price: PSP/u
discount: Disc. discount: Disc.
vat: VAT vat: VAT
amount: Amount amount: Amount
type: Type
taxBase: Tax base
tax: Tax
fee: Fee
total: Total total: Total
subtotal: Subtotal subtotal: Subtotal
taxBreakdown: Tax breakdown
packagings: Buckets and packaging
services: Services
vatType: VAT Type vatType: VAT Type
digitalSignature: Digital signature digitalSignature: Digital signature
ticket: Delivery note {0} ticket: Delivery note {0}
plantPassport: Plant passport plantPassport: Plant passport
packages: Packages packages: Packages
services:
title: Services
theader:
quantity: Qty.
concept: Concept
price: PSP/u
vat: VAT
amount: Amount
tfoot:
subtotal: Subtotal
warning: Deposit packaging will be invoiced if they have not been returned after 30 days of their delivery
packagings:
title: Buckets and packaging
theader:
reference: Reference
quantity: Quantity
concept: Concept
taxes:
title: Tax breakdown
theader:
type: Type
taxBase: Tax base
tax: Tax
fee: Fee
tfoot:
subtotal: Subtotal
total: Total

View File

@ -12,17 +12,37 @@ price: PVP/u
discount: Dto. discount: Dto.
vat: IVA vat: IVA
amount: Importe amount: Importe
type: Tipo
taxBase: Base imp.
tax: Tasa
fee: Cuota
total: Total total: Total
subtotal: Subtotal subtotal: Subtotal
taxBreakdown: Desglose impositivo
packagings: Cubos y embalajes
services: Servicios
vatType: Tipo de IVA vatType: Tipo de IVA
digitalSignature: Firma digital digitalSignature: Firma digital
ticket: Albarán {0} ticket: Albarán {0}
plantPassport: Pasaporte fitosanitario plantPassport: Pasaporte fitosanitario
packages: Bultos packages: Bultos
services:
title: Servicios
theader:
quantity: Cantidad
concept: Concepto
price: PVP/u
vat: IVA
amount: Importe
tfoot:
subtotal: Subtotal
warning: Los embalajes en depósito se facturarán si no han sido devueltos pasados 30 dias de su entrega
packagings:
title: Cubos y embalajes
theader:
reference: Referencia
quantity: Cantidad
concept: Concepto
taxes:
title: Desglose impositivo
theader:
type: Tipo
taxBase: Base imp.
tax: Tasa
fee: Cuota
tfoot:
subtotal: Subtotal
total: Total

View File

@ -12,17 +12,37 @@ price: PRIX/u
discount: Remise discount: Remise
vat: TVA vat: TVA
amount: Montant amount: Montant
type: Type
taxBase: Base imposable
tax: Taxe
fee: Quote
total: Total total: Total
subtotal: Total partiel subtotal: Total partiel
taxBreakdown: Répartition taxes
packagings: Bacs et emballages
services: Service
vatType: Type de TVA vatType: Type de TVA
digitalSignature: Signature numérique digitalSignature: Signature numérique
ticket: BL {0} ticket: BL {0}
plantPassport: Passeport phytosanitaire plantPassport: Passeport phytosanitaire
packages: Paquets packages: Paquets
services:
title: Service
theader:
quantity: Quantité
concept: Concept
price: PRIX/u
vat: TVA
amount: Montant
tfoot:
subtotal: Total partiel
warning: Les emballages de consigne seront facturés s'ils n'ont pas été retournés après 30 jours de leur livraison
packagings:
title: Bacs et emballages
theader:
reference: Référence
quantity: Quantité
concept: Concept
taxes:
title: Répartition taxes
theader:
type: Type
taxBase: Base imposable
tax: Taxe
fee: Quote
tfoot:
subtotal: Total partiel
total: Total

View File

@ -12,17 +12,37 @@ price: PVP/u
discount: Dto. discount: Dto.
vat: IVA vat: IVA
amount: Importe amount: Importe
type: Tipo
taxBase: Base imp.
tax: Taxa
fee: Quota
total: Total total: Total
subtotal: Sub-total subtotal: Sub-total
taxBreakdown: Desglose impositivo
packagings: Baldes e Embalagens
services: Serviços
vatType: Tipo de IVA vatType: Tipo de IVA
digitalSignature: Assinatura digital digitalSignature: Assinatura digital
ticket: Nota de Entrega {0} ticket: Nota de Entrega {0}
plantPassport: Passaporte vegetal plantPassport: Passaporte vegetal
packages: Pacotes packages: Pacotes
services:
title: Serviços
theader:
quantity: Quantidade
concept: Conceito
price: PVP/u
vat: IVA
amount: Quantia
tfoot:
subtotal: Subtotal
warning: Os pacotes do armazém serão cobrados se não forem devolvidos 30 dias após a entrega
packagings:
title: Baldes e Embalagens
theader:
reference: Referência
quantity: Quantidade
concept: Conceito
taxes:
title: Repartição de impostos
theader:
type: Cara
taxBase: Tributável
tax: Taxa
fee: Compartilhado
tfoot:
subtotal: Subtotal
total: Total