Improve naming conventions. Fail route first, then happy route. Abstract invoice no generation. Fix nested items validation.

This commit is contained in:
HenriT
2021-02-16 21:14:48 +02:00
parent 05b2a3f358
commit de779eda8a
3 changed files with 49 additions and 33 deletions

View File

@ -1,4 +1,5 @@
import storage from 'localforage'; import storage from 'localforage';
import TeamService from '@/services/team.service';
import { validate, generateInvoiceNumber } from '@/utils/helpers'; import { validate, generateInvoiceNumber } from '@/utils/helpers';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@ -14,7 +15,7 @@ class InvoiceService {
} }
async createInvoice(invoice) { async createInvoice(invoice) {
const team = storage.getItem('team'); const team = await TeamService.getTeam();
const invoices = await this.getInvoices(); const invoices = await this.getInvoices();
@ -23,8 +24,7 @@ class InvoiceService {
invoice.due_at = dayjs() invoice.due_at = dayjs()
.add(14, 'days') .add(14, 'days')
.format('YYYY-MM-DD'); .format('YYYY-MM-DD');
invoice.number = generateInvoiceNumber(dayjs() invoice.number = generateInvoiceNumber(invoices);
.format('YYYY'), invoices.length + 1);
invoice.late_fee = 0.5; invoice.late_fee = 0.5;
invoice.from_name = team.company_name; invoice.from_name = team.company_name;
invoice.from_address = team.company_address; invoice.from_address = team.company_address;
@ -49,7 +49,7 @@ class InvoiceService {
} }
async updateInvoice(invoice) { async updateInvoice(invoice) {
const necessaryFields = { const requiredFields = {
currency: 'Currency', currency: 'Currency',
vat_rate: 'Vat Rate', vat_rate: 'Vat Rate',
late_fee: 'Late Fee', late_fee: 'Late Fee',
@ -58,16 +58,15 @@ class InvoiceService {
number: 'Number', number: 'Number',
}; };
const validation = validate(necessaryFields, invoice); const errors = validate(requiredFields, invoice);
if (Object.keys(errors).length > 0) {
if (validation.length === 0) { return Promise.reject(errors);
}
const invoices = await this.getInvoices(); const invoices = await this.getInvoices();
const index = invoices.findIndex(item => item.id === invoice.id); const index = invoices.findIndex(item => item.id === invoice.id);
invoices[index] = invoice; invoices[index] = invoice;
return storage.setItem('invoices', invoices); return storage.setItem('invoices', invoices);
} }
return Promise.reject(validation);
}
async deleteInvoice(invoiceId) { async deleteInvoice(invoiceId) {
const invoices = await this.getInvoices(); const invoices = await this.getInvoices();
@ -77,7 +76,7 @@ class InvoiceService {
} }
async bookInvoice(invoice) { async bookInvoice(invoice) {
const necessaryFields = { const requiredFields = {
currency: 'Currency', currency: 'Currency',
vat_rate: 'Vat rate', vat_rate: 'Vat rate',
late_fee: 'Late fee', late_fee: 'Late fee',
@ -110,14 +109,14 @@ class InvoiceService {
}, },
}; };
const validation = await validate(necessaryFields, invoice); const errors = await validate(requiredFields, invoice);
if (Object.keys(errors).length > 0) {
return Promise.reject(errors);
}
if (validation.length === 0) {
invoice.status = 'booked'; invoice.status = 'booked';
return this.updateInvoice(invoice); return this.updateInvoice(invoice);
} }
return Promise.reject(validation);
}
} }
export default new InvoiceService(); export default new InvoiceService();

View File

@ -131,7 +131,7 @@ export default {
commit('clearErrors'); commit('clearErrors');
return InvoiceService.updateInvoice(getters.invoice) return InvoiceService.updateInvoice(getters.invoice)
.catch(err => commit('setErrors', err.response.data.errors)); .catch(err => commit('setErrors', err.errors));
}, },
async deleteInvoice(invoice) { async deleteInvoice(invoice) {
const res = await InvoiceService.deleteInvoice(invoice.id); const res = await InvoiceService.deleteInvoice(invoice.id);
@ -161,11 +161,9 @@ export default {
commit('clearErrors'); commit('clearErrors');
try { try {
console.log('tryBookInvoice');
const res = await InvoiceService.bookInvoice(getters.invoice); const res = await InvoiceService.bookInvoice(getters.invoice);
return dispatch('getInvoice', res.invoice_id); return dispatch('getInvoice', res.invoice_id);
} catch (err) { } catch (err) {
console.log(err);
commit('setErrors', err.errors); commit('setErrors', err.errors);
} }
}, },

View File

@ -1,4 +1,6 @@
/* eslint-disable */ /* eslint-disable */
import dayjs from '../services/invoice.service';
export function uuidv4() { export function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, var r = Math.random() * 16 | 0,
@ -32,25 +34,42 @@ export function pick(obj, map) {
} }
export function validate(neededFields, fieldsToValidate) { export function validate(requiredFields, input) {
const validationErrors = {}; const errors = {};
for (const [key, value] of Object.entries(neededFields)) { for (let [key, value] of Object.entries(requiredFields)) {
if (Array.isArray(fieldsToValidate[key])) { if (Array.isArray(input[key])) {
fieldsToValidate[key].forEach((item) => { input[key].forEach((subInput, index) => {
for (let [subKey, subValue] of Object.entries(value)) {
const error = validateField(subInput, subKey, subValue);
if (error) {
errors[`${key}.${index}.${subKey}`] = error;
}
}
}); });
} else {
const error = validateField(input, key, value);
if (error) {
errors[key] = error;
} }
if (!fieldsToValidate.hasOwnProperty(key) || !fieldsToValidate[key] || fieldsToValidate[key].length === 0) {
validationErrors[key] = [`Field ${value} is required`];
} }
} }
console.log('errors', validationErrors); return { errors };
return { errors: validationErrors }; }
export function validateField(input, field, label) {
if (!input.hasOwnProperty(field) || !input[field] || input[field].length === 0) {
return [`${label} is required`];
}
return null;
} }
export function generateInvoiceNumber(date, number) { export function generateInvoiceNumber(invoices) {
const date = dayjs()
.format('YYYY');
const number = invoices.length + 1;
return `${date}-${number}`; return `${date}-${number}`;
} }