UI para facturar
This commit is contained in:
parent
d396f5720e
commit
e6c48d239d
|
@ -35,6 +35,15 @@ class StorageEngine(object):
|
|||
def _get_satkey(self, values):
|
||||
return main.get_sat_key(values['key'])
|
||||
|
||||
def _get_series(self, values):
|
||||
return main.Folios.get_all()
|
||||
|
||||
def _get_monedas(self, values):
|
||||
return main.SATMonedas.get_activos()
|
||||
|
||||
def _get_usocfdi(self, values):
|
||||
return main.SATUsoCfdi.get_activos()
|
||||
|
||||
def delete(self, table, id):
|
||||
if table == 'partner':
|
||||
return main.Socios.remove(id)
|
||||
|
|
|
@ -160,7 +160,7 @@ class Folios(BaseModel):
|
|||
serie = TextField()
|
||||
inicio = IntegerField(default=1)
|
||||
default = BooleanField(default=False)
|
||||
usar_con = TextField(default='T')
|
||||
usar_con = TextField(default='')
|
||||
|
||||
class Meta:
|
||||
order_by = ('-default', 'serie', 'inicio')
|
||||
|
@ -168,6 +168,18 @@ class Folios(BaseModel):
|
|||
(('serie', 'inicio'), True),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_all(cls):
|
||||
rows = (Folios
|
||||
.select(
|
||||
Folios.id,
|
||||
Folios.serie.alias('value'),
|
||||
Folios.usar_con,
|
||||
)
|
||||
.dicts()
|
||||
)
|
||||
return tuple(rows)
|
||||
|
||||
|
||||
class Categorias(BaseModel):
|
||||
categoria = TextField()
|
||||
|
@ -269,6 +281,17 @@ class SATMonedas(BaseModel):
|
|||
(('key', 'name'), True),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_activos(cls):
|
||||
rows = (SATMonedas
|
||||
.select(
|
||||
SATMonedas.key.alias('id'),
|
||||
SATMonedas.name.alias('value'))
|
||||
.where(SATMonedas.activo==True)
|
||||
.dicts()
|
||||
)
|
||||
return tuple(rows)
|
||||
|
||||
|
||||
class SATImpuestos(BaseModel):
|
||||
key = TextField(index=True)
|
||||
|
@ -305,6 +328,20 @@ class SATUsoCfdi(BaseModel):
|
|||
(('key', 'name'), True),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_activos(cls):
|
||||
rows = (SATUsoCfdi
|
||||
.select(
|
||||
SATUsoCfdi.key.alias('id'),
|
||||
SATUsoCfdi.name.alias('value'),
|
||||
SATUsoCfdi.fisica,
|
||||
SATUsoCfdi.moral,
|
||||
)
|
||||
.where(SATUsoCfdi.activo==True)
|
||||
.dicts()
|
||||
)
|
||||
return tuple(rows)
|
||||
|
||||
|
||||
class Addendas(BaseModel):
|
||||
nombre = TextField(unique=True)
|
||||
|
@ -344,6 +381,7 @@ class Socios(BaseModel):
|
|||
forma_pago = ForeignKeyField(SATFormaPago, null=True)
|
||||
condicion_pago = ForeignKeyField(CondicionesPago, null=True)
|
||||
addenda = ForeignKeyField(Addendas, null=True)
|
||||
uso_cfdi = ForeignKeyField(SATUsoCfdi, null=True)
|
||||
tags = ManyToManyField(Tags, related_name='socios_tags')
|
||||
|
||||
def __str__(self):
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
.right {
|
||||
text-align: right;
|
||||
}
|
||||
.right_footer {
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
font-size: 125%;
|
||||
color: DarkRed;
|
||||
}
|
||||
|
||||
.cmd_close_partner div button {
|
||||
background-color: red !important;
|
||||
|
|
|
@ -1,11 +1,80 @@
|
|||
var query = []
|
||||
var grid = null
|
||||
|
||||
|
||||
function get_series(){
|
||||
webix.ajax().get('/values/series', function(text, data){
|
||||
var values = data.json()
|
||||
table_series.clear()
|
||||
table_series.insert(values)
|
||||
pre = values[0]
|
||||
$$('lst_serie').getList().parse(values)
|
||||
$$('lst_serie').setValue(pre.id)
|
||||
if(pre.usar_con){
|
||||
$$('lst_tipo_comprobante').setValue(pre.usar_con)
|
||||
$$('lst_tipo_comprobante').config.readonly = true
|
||||
$$('lst_tipo_comprobante').refresh()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function get_forma_pago(){
|
||||
webix.ajax().get('/values/formapago', function(text, data){
|
||||
var values = data.json()
|
||||
pre = values[0]
|
||||
$$('lst_forma_pago').getList().parse(values)
|
||||
$$('lst_forma_pago').setValue(pre.id)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function get_monedas(){
|
||||
webix.ajax().get('/values/monedas', function(text, data){
|
||||
var values = data.json()
|
||||
pre = values[0]
|
||||
$$('lst_moneda').getList().parse(values)
|
||||
$$('lst_moneda').setValue(pre.id)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function get_uso_cfdi(){
|
||||
webix.ajax().get('/values/usocfdi', function(text, data){
|
||||
var values = data.json()
|
||||
pre = values[0]
|
||||
table_usocfdi.clear()
|
||||
table_usocfdi.insert(values)
|
||||
$$('lst_uso_cfdi').getList().parse(values)
|
||||
$$('lst_uso_cfdi').setValue(pre.id)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function default_config(){
|
||||
get_series()
|
||||
get_forma_pago()
|
||||
get_monedas()
|
||||
get_uso_cfdi()
|
||||
table_pt.clear()
|
||||
table_totals.clear()
|
||||
}
|
||||
|
||||
|
||||
function cmd_new_invoice_click(id, e, node){
|
||||
var form = $$('form_invoice')
|
||||
var grid_totals = $$('grid_totals')
|
||||
grid = $$('grid_details')
|
||||
|
||||
$$('form_invoice').adjust();
|
||||
$$("multi_invoices").setValue("invoices_new")
|
||||
|
||||
};
|
||||
default_config()
|
||||
form.adjust()
|
||||
form.setValues({id: 0, id_partner: 0, lbl_partner: 'Ninguno'})
|
||||
grid.clearAll()
|
||||
grid_totals.clearAll()
|
||||
grid_totals.add({id: 1, concepto: 'SubTotal', importe: 0})
|
||||
$$('multi_invoices').setValue('invoices_new')
|
||||
form.focus('search_partner_id')
|
||||
}
|
||||
|
||||
|
||||
function cmd_edit_invoice_click(id, e, node){
|
||||
|
@ -22,23 +91,20 @@ function cmd_delete_invoice_click(id, e, node){
|
|||
};
|
||||
|
||||
|
||||
function cmd_save_invoice_click(id, e, node){
|
||||
var form = this.getFormView();
|
||||
function cmd_timbrar_click(id, e, node){
|
||||
var form = this.getFormView()
|
||||
|
||||
if (!form.validate()) {
|
||||
webix.message({ type:"error", text:"Valores inválidos" });
|
||||
webix.message({type: 'error', text: 'Valores inválidos'})
|
||||
return
|
||||
}
|
||||
|
||||
$$('form_invoice').clear();
|
||||
$$("multi_invoices").setValue("invoices_home")
|
||||
webix.message({type:"success", text: "Factura guardada correctamente"});
|
||||
|
||||
};
|
||||
$$('multi_invoices').setValue('invoices_home')
|
||||
webix.message({type:"success", text: "Factura guardada correctamente"})
|
||||
}
|
||||
|
||||
|
||||
function cmd_cancel_invoice_click(id, e, node){
|
||||
|
||||
$$("multi_invoices").setValue("invoices_home")
|
||||
|
||||
};
|
||||
function cmd_close_invoice_click(id, e, node){
|
||||
$$('multi_invoices').setValue('invoices_home')
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ var controllers = {
|
|||
$$("cmd_new_invoice").attachEvent("onItemClick", cmd_new_invoice_click);
|
||||
$$("cmd_edit_invoice").attachEvent("onItemClick", cmd_edit_invoice_click);
|
||||
$$("cmd_delete_invoice").attachEvent("onItemClick", cmd_delete_invoice_click);
|
||||
$$("cmd_save_invoice").attachEvent("onItemClick", cmd_save_invoice_click);
|
||||
$$("cmd_cancel_invoice").attachEvent("onItemClick", cmd_cancel_invoice_click);
|
||||
$$('cmd_timbrar').attachEvent('onItemClick', cmd_timbrar_click)
|
||||
$$('cmd_close_invoice').attachEvent('onItemClick', cmd_close_invoice_click)
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ var table_config = db.addCollection('config')
|
|||
var table_taxes = db.addCollection('taxes')
|
||||
var table_pt = db.addCollection('productstaxes')
|
||||
var table_totals = db.addCollection('totals', {unique: ['tax']})
|
||||
var table_series = db.addCollection('series')
|
||||
var table_usocfdi = db.addCollection('usocfdi')
|
||||
|
||||
|
||||
function show(values){
|
||||
|
|
|
@ -7,20 +7,34 @@ var toolbar_invoices = [
|
|||
autowidth: true, icon: "pencil"},
|
||||
{view: "button", id: "cmd_delete_invoice", label: "Eliminar", type: "iconButton",
|
||||
autowidth: true, icon: "minus"},
|
||||
];
|
||||
]
|
||||
|
||||
|
||||
function doc_xml(obj){
|
||||
var node = "<img src='/static/img/file-xml.png' height='20' width='20' style='margin: 5px 0px'/>"
|
||||
return node
|
||||
}
|
||||
|
||||
|
||||
var grid_invoices_cols = [
|
||||
{id: "id", header:"ID", hidden:true},
|
||||
{id: "serie", header: ["Serie", {content: "selectFilter"}], adjust: "data", sort:"string"},
|
||||
{id: "folio", header: ["Folio", {content: "numberFilter"}], adjust: "data", sort:"int", css: "cell_right"},
|
||||
{id: "uuid", header: ["UUID", {content: "textFilter"}], adjust: "data", sort:"string"},
|
||||
{id: "serie", header: ["Serie", {content: "selectFilter"}], adjust: "data",
|
||||
sort:"string"},
|
||||
{id: "folio", header: ["Folio", {content: "numberFilter"}], adjust: "data",
|
||||
sort:"int", css: "cell_right"},
|
||||
{id: 'xml', header: '', adjust: 'data', template: doc_xml},
|
||||
{id: "uuid", header: ["UUID", {content: "textFilter"}], adjust: "data",
|
||||
sort:"string"},
|
||||
{id: "fecha", header: ["Fecha y Hora"], adjust: "data", sort:"string"},
|
||||
{id: "tipo", header: ["Tipo", {content: "selectFilter"}], adjust: "data", sort:"string"},
|
||||
{id: "estatus", header: ["Estatus", {content: "selectFilter"}], adjust: "data", sort:"string"},
|
||||
{id: "total", header: ["Total M.N.", {content: "numberFilter"}], width: 150, sort:"int", format: webix.i18n.priceFormat, css: "cell_right"},
|
||||
{id: "partner", header: ["Razón Social", {content: "selectFilter"}], fillspace:true, sort:"string"},
|
||||
];
|
||||
{id: "tipo_comprobante", header: ["Tipo", {content: "selectFilter"}],
|
||||
adjust: 'header', sort: 'string'},
|
||||
{id: "estatus", header: ["Estatus", {content: "selectFilter"}],
|
||||
adjust: "data", sort:"string"},
|
||||
{id: 'total_mn', header: ['Total M.N.', {content: 'numberFilter'}], width: 150,
|
||||
sort: 'int', format: webix.i18n.priceFormat, css: 'right'},
|
||||
{id: "cliente", header: ["Razón Social", {content: "selectFilter"}],
|
||||
fillspace:true, sort:"string"},
|
||||
]
|
||||
|
||||
|
||||
var grid_invoices = {
|
||||
|
@ -36,14 +50,18 @@ var grid_invoices = {
|
|||
|
||||
|
||||
var grid_details_cols = [
|
||||
{id:"id", header:"ID", hidden: true},
|
||||
{id:"key", header:{text: 'Clave', css: 'center'}, width: 100},
|
||||
{id:"description", header:{text: 'Descripción', css: 'center'}, fillspace: true},
|
||||
{id:"unidad", header:{text: 'Unidad', css: 'center'}, width: 100},
|
||||
{id:"cant", header:{text: 'Cantidad', css: 'center'}, width: 100, format: webix.i18n.priceFormat, css:'right'},
|
||||
{id:"price", header:{text: 'Valor Unitario', css: 'center'}, width: 100, format: webix.i18n.priceFormat, css:'right'},
|
||||
{id:"importe", header:{text: 'Importe', css: 'center'}, width: 150, format: webix.i18n.priceFormat, css:'right'},
|
||||
];
|
||||
{id: "id", header:"ID", hidden: true},
|
||||
{id: 'delete', header: '', width: 30, css: 'delete'},
|
||||
{id: "key", header:{text: 'Clave', css: 'center'}, width: 100},
|
||||
{id: "description", header:{text: 'Descripción', css: 'center'},
|
||||
fillspace: true},
|
||||
{id: "unit", header:{text: 'Unidad', css: 'center'}, width: 100},
|
||||
{id: 'cant', header: {text: 'Cantidad', css: 'center'}, width: 100,
|
||||
format: webix.i18n.numberFormat, css:'right', editor: 'text'},
|
||||
{id: "price", header:{text: 'Valor Unitario', css: 'center'}, width: 100,
|
||||
format: webix.i18n.priceFormat, css:'right', editor: 'text'},
|
||||
{id: "importe", header:{text: 'Importe', css: 'center'}, width: 150, format: webix.i18n.priceFormat, css:'right'},
|
||||
]
|
||||
|
||||
|
||||
var grid_details = {
|
||||
|
@ -53,18 +71,181 @@ var grid_details = {
|
|||
adjust: true,
|
||||
autoheight: true,
|
||||
columns: grid_details_cols,
|
||||
data: [
|
||||
{id:1, key:'001', description:'Uno', unidad:'Pieza', cant:1, price:100, importe:100},
|
||||
{id:2, key:'002', description:'Dos', unidad:'Pieza', cant:2, price:200, importe:400},
|
||||
]
|
||||
};
|
||||
data: []
|
||||
}
|
||||
|
||||
|
||||
var grid_totals_cols = [
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'concepto', header: 'Concepto', width: 200,
|
||||
footer: {text: 'TOTAL', css:'right_footer'}, css:'right'},
|
||||
{id: 'importe', header: 'Importe', width: 150,
|
||||
footer: {content: 'summColumn', css:'right_footer'},
|
||||
format: webix.i18n.priceFormat, css:'right'},
|
||||
]
|
||||
|
||||
|
||||
var grid_totals = {
|
||||
view: 'datatable',
|
||||
id: 'grid_totals',
|
||||
select: false,
|
||||
width: 350,
|
||||
header: false,
|
||||
footer: true,
|
||||
autoheight: true,
|
||||
columns: grid_totals_cols,
|
||||
data: [{id: 1, concepto: 'SubTotal', importe: 0}]
|
||||
}
|
||||
|
||||
|
||||
var suggest_partners = {
|
||||
view: 'gridsuggest',
|
||||
id: 'grid_partners_found',
|
||||
name: 'grid_partners_found',
|
||||
body: {
|
||||
autoConfig: false,
|
||||
header: false,
|
||||
columns: [{id:"id", hidden: true}, {id:'name', adjust:'data'}, {id:'rfc', adjust:'data'}],
|
||||
dataFeed:function(text){
|
||||
if (text.length > 2){
|
||||
this.load('/values/partner?name=' + text)
|
||||
}else{
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var suggest_products = {
|
||||
view: 'gridsuggest',
|
||||
id: 'grid_products_found',
|
||||
name: 'grid_products_found',
|
||||
body: {
|
||||
autoConfig: false,
|
||||
header: true,
|
||||
columns: [
|
||||
{id: 'id', hidden: true},
|
||||
{id: 'key', adjust: 'data'},
|
||||
{id: 'description', adjust: 'data'},
|
||||
{id: 'unit', adjust: 'data'},
|
||||
{id: 'price', adjust: 'data', format: webix.i18n.priceFormat}
|
||||
],
|
||||
dataFeed:function(text){
|
||||
if (text.length > 2){
|
||||
this.load('/values/product?name=' + text)
|
||||
}else{
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var body_comprobante = {cols: [
|
||||
{
|
||||
view: 'richselect',
|
||||
id: 'lst_tipo_comprobante',
|
||||
label: 'Tipo',
|
||||
labelPosition: 'top',
|
||||
required: true,
|
||||
value: 'I',
|
||||
options: [
|
||||
{id: 'I', value: 'Ingreso'},
|
||||
{id: 'E', value: 'Egreso'},
|
||||
{id: 'T', value: 'Traslado'}
|
||||
]
|
||||
},
|
||||
{
|
||||
view: 'richselect',
|
||||
id: 'lst_serie',
|
||||
label: 'Serie',
|
||||
labelPosition: 'top',
|
||||
options: [],
|
||||
//~ options: '/values/series',
|
||||
//~ on: {
|
||||
//~ onAfterRender: webix.once(function(){
|
||||
//~ this.getPopup().getList().waitData.then(webix.bind(function(){
|
||||
//~ this.setValue(this.getPopup().getList().getFirstId())
|
||||
//~ }, this))
|
||||
//~ }),
|
||||
//~ }
|
||||
}
|
||||
]}
|
||||
|
||||
|
||||
var opt_metodo_pago = [
|
||||
{id: 'PUE', value: 'Pago en una sola exhibición'},
|
||||
{id: 'PPD', value: 'Pago en parcialidades o diferido'}
|
||||
]
|
||||
|
||||
|
||||
//~ var body_serie_folio = {
|
||||
//~ view: 'richselect',
|
||||
//~ id: 'cbo_serie_folio',
|
||||
//~ options: '/values/seriefolio'
|
||||
//~ }
|
||||
|
||||
|
||||
var body_opciones = {rows: [
|
||||
{view: 'richselect', id: 'lst_forma_pago', label: 'Forma de Pago',
|
||||
labelPosition: 'top', required: true, options: []},
|
||||
{view: 'richselect', id: 'lst_metodo_pago', label: 'Método de Pago',
|
||||
labelPosition: 'top', options: opt_metodo_pago, value: 'PUE',
|
||||
required: true},
|
||||
{view: 'text', id: 'txt_condicion_pago', label: 'Condiciones de Pago',
|
||||
labelPosition: 'top'},
|
||||
]}
|
||||
|
||||
|
||||
var body_moneda = {cols: [
|
||||
{view: 'richselect', id: 'lst_moneda', label: 'Nombre',
|
||||
labelPosition: 'top', required: true, options: []},
|
||||
{view: 'text', type: 'text', id: 'txt_tipo_cambio', value: '1.00',
|
||||
label: 'Tipo de Cambio', labelPosition: 'top', required: true,
|
||||
invalidMessage: 'Captura un valor númerico', inputAlign: 'right',
|
||||
readonly: true}
|
||||
]}
|
||||
|
||||
|
||||
var body_uso_cfdi = {
|
||||
view: 'richselect',
|
||||
id: 'lst_uso_cfdi',
|
||||
required: true,
|
||||
options: []
|
||||
}
|
||||
|
||||
|
||||
var controls_generate = [
|
||||
{view: "text", id: "search_partner", name: "search_partner", label: "Buscar Cliente", required: true, labelPosition: "top"},
|
||||
{view: "text", id: "search_product", name: "search_product", label: "Buscar Producto", required: true, labelPosition: "top"},
|
||||
{view:"label", label:'Detalle', height:30, align:'left'},
|
||||
{cols: [ {rows:[
|
||||
{view: 'fieldset', label: 'Buscar Cliente', body: {rows: [
|
||||
{cols: [
|
||||
{view:"search", id:"search_partner_id", name:"search_partner_id",
|
||||
label:"por Clave", labelPosition:'top', maxWidth:200,
|
||||
placeholder:'Captura la clave'},
|
||||
{view:"search", id:"search_partner_name", name:"search_partner_name", label:"por Nombre o RFC", labelPosition:'top', suggest:suggest_partners, placeholder:'Captura al menos tres letras'},
|
||||
]},
|
||||
{cols: [{view: "label", id: "lbl_partner_title", name: "lbl_partner_title", label: 'Seleccionado: ', autowidth:true},
|
||||
{view: "label", id: "lbl_partner", name: "lbl_partner", label: 'Ninguno'},
|
||||
]}
|
||||
]}},
|
||||
{view: 'fieldset', label: 'Buscar Producto', body: {rows: [
|
||||
{cols: [{view:"search", id:"search_product_id", name:"search_product_id", label:"por Clave", labelPosition:'top', maxWidth:200, placeholder:'Captura la clave'},
|
||||
{view:"search", id:"search_product_name", name:"search_product_name", label:"por Descripción", labelPosition:'top', suggest:suggest_products, placeholder:'Captura al menos tres letras'},
|
||||
]},
|
||||
]}}
|
||||
]},
|
||||
{maxWidth: 10},
|
||||
{maxWidth: 300, rows: [
|
||||
{view: 'fieldset', label: 'Comprobante', body: body_comprobante},
|
||||
{view: 'fieldset', label: 'Opciones de Pago', body: body_opciones},
|
||||
{view: 'fieldset', label: 'Moneda', body: body_moneda},
|
||||
{view: 'fieldset', label: 'Uso del CFDI', body: body_uso_cfdi},
|
||||
]}
|
||||
]},
|
||||
{view: 'label', label: 'Detalle', height: 30, align: 'left'},
|
||||
grid_details,
|
||||
{minHeight: 15, maxHeight: 15},
|
||||
{cols: [{}, grid_totals]}
|
||||
]
|
||||
|
||||
|
||||
|
@ -79,13 +260,14 @@ var controls_invoices = [
|
|||
{rows: [
|
||||
{ template:"", type: "section" },
|
||||
{ margin: 10, cols: [{},
|
||||
{view: "button", id: "cmd_save_invoice", label: "Guardar" , type: "form", autowidth: true, align:"center"},
|
||||
{view: "button", id: "cmd_send_invoice", label: "Timbrar" , type: "form", autowidth: true, align:"center"},
|
||||
{view: "button", id: "cmd_cancel_invoice", label: "Cancelar" , type: "danger", autowidth: true, align:"center"},
|
||||
{view: "button", id: "cmd_timbrar", label: "Timbrar",
|
||||
type: "form", autowidth: true, align:"center"},
|
||||
{view: 'button', id: 'cmd_close_invoice', label: 'Salir',
|
||||
type: 'danger', autowidth: true, align: 'center'},
|
||||
{}]
|
||||
},
|
||||
]}
|
||||
];
|
||||
]
|
||||
|
||||
|
||||
var form_invoice = {
|
||||
|
@ -93,24 +275,19 @@ var form_invoice = {
|
|||
cols: [{
|
||||
view: "form",
|
||||
id: "form_invoice",
|
||||
//~ width: 800,
|
||||
complexData: true,
|
||||
elements: controls_invoices,
|
||||
//~ rules: {
|
||||
//~ description: function(value){ return value.trim() != ""; },
|
||||
//~ unidad: function(value){ return value.trim() != ""; },
|
||||
//~ price: function(value){ return value.trim() != ""; },
|
||||
//~ }
|
||||
}]
|
||||
};
|
||||
|
||||
|
||||
var multi_invoices = {
|
||||
id: "multi_invoices",
|
||||
view: 'multiview',
|
||||
animate: true,
|
||||
cells:[
|
||||
{id: "invoices_home", rows:[
|
||||
{view:"toolbar", elements: toolbar_invoices},
|
||||
{view: "toolbar", elements: toolbar_invoices},
|
||||
grid_invoices,
|
||||
]},
|
||||
{id: "invoices_new", rows:[form_invoice, {}]}
|
||||
|
|
Loading…
Reference in New Issue