<% /* $Revision$ $Id$ File: model_invoices.inc Description: Factuur model. Parameters: Context: Notes: TODO: definitieve naamgeving verifieren TODO: autorisaties voor scope=fo|bo We had a discussion. The references (order, contract, purchaseorder) are now present by their foreign nodes. We ourselves want the creditor of the invoice in the result, it is logically a property of an invoice which we technically do not store with the invoice. Formally the creditor should be obtained by a subsequent call to the corresponing API. Alternatively we could add those 3 optional nodes with an include option which is merely designed for 1:n relations, not n:1 like this one. We do not want to slide down from our purest REST forms (yet) so we made the compromise of these 2 readonly fields. Let's see how it holds. */ %> <% function model_invoices(fin_key, params) { params = params || {}; this.module = "FIN"; this.table = "fin_factuur"; this.primary = "fin_factuur_key"; this.records_name = "invoices"; this.record_name = "invoice"; // Het interne factuurnr is de id, het externe nummer is name this.fields = {"id" : { dbs: "fin_factuur_key", typ: "key", filter: "exact" }, "invoicedate" : { dbs: "fin_factuur_datum", typ: "datetime", track: true, label: L("lcl_fin_findate"), filter: "range" }, /*readonly*/ "creditor" : { dbs: "prs_bedrijf_key", typ: "key", foreign: "prs_bedrijf", track: true, label: L("lcl_ord_company_uit"), filter: "exact", sql: "COALESCE(mld_opdr.mld_uitvoerende_keys, bes_bestelopdr.prs_bedrijf_key, cnt_contract.cnt_prs_bedrijf_key)" }, /*readonly*/ "referencetype" : { dbs: "dummy", typ: "varchar", filter: "exact", sql: "DECODE(fin_factuur.mld_opdr_key, NULL, DECODE(fin_factuur.bes_bestelopdr_key, NULL, DECODE(fin_factuur.cnt_contract_key, NULL, '?', 'C'), 'B'), 'O')" }, "name" : { dbs: "fin_factuur_nr", typ: "varchar", track: true, label: L("lcl_fin_invoice_nr_extern"), filter: "exact" }, "order" : { dbs: "mld_opdr_key", typ: "key", foreign: "mld_opdr", filter: "exact"}, "contract" : { dbs: "cnt_contract_key", typ: "key", foreign: "cnt_contract", filter: "exact"}, "purchaseorder" : { dbs: "bes_bestelopdr_key", typ: "key", foreign: "bes_bestelopdr", filter: "exact"}, "total" : { dbs: "fin_factuur_totaal", typ: "float", "iscurrency": true, track: true, label: L("lcl_fin_totaal_bedrag"), filter: "range" }, "vat" : { dbs: "fin_factuur_totaal_btw", typ: "float", "iscurrency": true, track: true, label: L("lcl_fin_totaal_bedrag_btw"), filter: "range" }, "finstatus" : { dbs: "fin_factuur_statuses_key", typ: "key", foreign: fin.getfinstatustext, track: true, label: L("lcl_fin_fin_status"), filter: "exact" }, "accountingperiod": { dbs: "fin_factuur_boekmaand", multiedit: true, typ: "varchar", track: true, label: L("lcl_fin_divide_period"), filter: "exact" }, "debiteur_nr" : { dbs: "fin_factuur_debiteur_nr", multiedit: true, typ: "varchar", track: true, label: L("lcl_fin_debtor_nr"), filter: "like" }, "costtype" : { dbs: "prs_kostensoort_key", multiedit: true, typ: "key", foreign: "prs_kostensoort", track: true, label: L("lcl_shared_charge_type"), filter: "exact" }, "contact" : { dbs: "prs_perslid_key_user", multiedit: true, typ: "key", foreign: "prs_perslid", track: true, label: L("lcl_mld_name"), filter: "exact" }, "validater" : { dbs: "prs_perslid_key_goedkeur", typ: "key", foreign: "prs_perslid", track: true, label: L("lcl_fin_goedkeurder"), filter: "exact" }, "remark" : { dbs: "fin_factuur_opmerking", typ: "varchar", track: true, label: L("lcl_fin_remark"), filter: "like" } }; this.includes = {"invoicelines": { model: model_invoicelines, joinfield: "fin_factuur_key", enable_update: true }, "custom_fields" : { model: new model_custom_fields(this, new model_fin_kenmerk({ internal: true }), { readman: true, readuse: true }), joinfield: "flexparentkey" }, "tracking": { model: new model_tracking(['contract']), joinfield: "trackingrefkey" } }; function _pre_analyze_fields (params, jsondata) /* analyseer inkomende jsondata, common voor PUT en POST */ { // De factuurbedragen worden berekend uit de factuurregels. Eventuele waarden die hier gezet zijn negeren. jsondata.total = 0; jsondata.vat = 0; // Status van 3 (foute import) moet bij saven op 2 worden gezet. var fin_status_key = jsondata.status; if (fin_status_key == 3) fin_status_key = 2; // Status 6 (Akkoord) moet bij saven op 2 (Ingevoerd) worden gezet. Factuur dient indien nodig weer gefiatteerd te worden. if (fin_status_key == 6) fin_status_key = 2; jsondata.status = fin_status_key; }; function _analyze_fields (dbfields, params, jsondata) /* analyseer inkomende data, common voor PUT en POST */ { }; function _validate_fields (dbfields, params, jsondata) /* valideer fields, alle constraints die niet door de database worden afgevangen */ { }; this.REST_GET = function _GET(params) { var this_fin = fin.func_enabled_factuur(params.filter.id || -1); user.auth_required_or_abort(this_fin.canReadAny); var query = api2.sqlfields(params, this ); query.wheres.push("fin_factuur_verwijder IS NULL"); if (/* self */ 0) { query.wheres.push("prs_perslid_key_user=" + user_key); } else { // TODO: disc3d conditie voor de geldendende autfunction toevoegen } query.tables.push("mld_opdr"); query.wheres.push("fin_factuur.mld_opdr_key = mld_opdr.mld_opdr_key(+)"); query.tables.push("bes_bestelopdr"); query.wheres.push("fin_factuur.bes_bestelopdr_key = bes_bestelopdr.bes_bestelopdr_key(+)"); query.tables.push("cnt_contract"); query.wheres.push("fin_factuur.cnt_contract_key = cnt_contract.cnt_contract_key(+)"); var wheres = api2.sqlfilter(params, this); query.wheres = query.wheres.concat(wheres); var sql = "SELECT " + query.selects.join(", ") + " FROM " + query.tables.join(", ") + " WHERE " + query.wheres.join(" AND " ) + " ORDER BY fin_factuur_key"; if (query.orderbys.length) sql += ", " + query.orderbys.join(", "); var json = api2.sql2json (params, sql, this ); return json; }; this.REST_PUT = function (params, jsondata, the_key) /* update invoice */ { var fin_key = the_key; var this_fin = fin.func_enabled_factuur(fin_key); user.auth_required_or_abort(this_fin.canChange); // Geen wijzigingen toestaan bij onvoldoende rechten. // _pre_analyze_fields(params, jsondata); var dbfields = api2.update_fields(params, this, jsondata); // Build updater _analyze_fields(dbfields, params, jsondata); _validate_fields(dbfields, params, jsondata); // var wheres = [" fin_factuur_key = " + fin_key]; var finUpd = buildTrackingUpdate("fin_factuur", wheres.join(" AND " ), dbfields, { noValidateToken: true }); var err = Oracle.Execute(finUpd.sql, true); if (err.friendlyMsg) abort_with_warning(err.friendlyMsg); var fintrack = api2.process_includes(params, this, jsondata, the_key); // update nog tracken if (fin_key > 0) { shared.trackaction("FINUPD", fin_key, L("lcl_fin_is_finupdtrack").format(fin_key) + (finUpd.trackarray.length > 0? "\n" : "") + finUpd.trackarray.join("\n")); }; return { key: fin_key }; }; this.REST_POST = function (params, jsondata) /* new invoice */ { var this_fin = fin.func_enabled_factuur(-1); user.auth_required_or_abort(this_fin.canChange); // Geen wijzigingen toestaan bij onvoldoende rechten. params.isNew = true; // negeer eventuele bestaande keys _pre_analyze_fields(params, jsondata); var dbfields = api2.update_fields(params, this, jsondata); // Build updater _analyze_fields(dbfields, params, jsondata); _validate_fields(dbfields, params, jsondata); dbfields["id"] = { dbs: "fin_factuur_key", typ: "key", seq: "fin_s_fin_factuur_key" }; var finIns = buildInsert("fin_factuur", dbfields, { noValidateToken: true} ); var factuur_key = finIns.sequences["fin_factuur_key"]; var sql = finIns.sql; var err = Oracle.Execute(sql, true); if (err.friendlyMsg) abort_with_warning(err.friendlyMsg); var fintrack = api2.process_includes(params, this, jsondata, factuur_key); shared.trackaction("FINNEW", factuur_key); return { key: factuur_key }; }; this.REST_DELETE = function (params, the_key) /* delete invoice */ { var factuur_key = the_key; var this_fin = fin.func_enabled_factuur(factuur_key); user.auth_required_or_abort(this_fin.canDelete); if (this_fin.canDelete) // Dubbel op: bij canDelete=false komt hij hier niet meer. { // Verwijderdatum van de factuur zetten en niet fysiek verwijderen var sql = "UPDATE fin_factuur" + " SET fin_factuur_verwijder = SYSDATE" + " WHERE fin_factuur_verwijder IS NULL" + " AND fin_factuur_key = " + factuur_key; oRs = Oracle.Execute(sql); } } if (fin_key > 0) { params.filter = params.filter || {}; params.filter.id = fin_key; if (! ("include" in params) ) params.include = { include: ["custom_fields"]}; var xxx_array = this.REST_GET(params); if (!xxx_array.length) shared.record_not_found(); this.data = xxx_array[0]; } } %>