Commit 18447b4b authored by Frank Bergmann's avatar Frank Bergmann

intranet-invoices from scratch

parent 2787859f
-- /packages/intranet-invoices/sql/oracle/intranet-invoices-backup.sql -- /packages/intranet-invoices/sql/oracle/intranet-invoices-backup.sql
-- --
-- Copyright (C) 2004 Project/Open -- Copyright (C) 2003-2004 Project/Open
-- --
-- This program is free software. You can redistribute it -- All rights reserved. Please check
-- and/or modify it under the terms of the GNU General -- http://www.project-open.com/license/ for details.
-- Public License as published by the Free Software Foundation;
-- either version 2 of the License, or (at your option)
-- any later version. This program is distributed in the
-- hope that it will be useful, but WITHOUT ANY WARRANTY;
-- without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU General Public License for more details.
-- --
-- @author frank.bergmann@project-open.com -- @author frank.bergmann@project-open.com
-- 100 im_projects -- 100 im_projects
-- 101 im_project_roles -- 101 im_project_roles
...@@ -303,15 +296,15 @@ delete from im_views where view_id = 193; ...@@ -303,15 +296,15 @@ delete from im_views where view_id = 193;
insert into im_views (view_id, view_name, view_sql insert into im_views (view_id, view_name, view_sql
) values (193, 'im_project_invoice_map', ' ) values (193, 'im_project_invoice_map', '
SELECT SELECT
pg.group_name as project_name, p.project_name,
i.invoice_nr i.invoice_nr
FROM FROM
im_project_invoice_map m, acs_rels r,
user_groups pg, project p,
im_invoices i im_invoices i
WHERE WHERE
m.project_id = pg.group_id r.object_id_one = p.project_id
and m.invoice_id = i.invoice_id and r.object_id_two = i.invoice_id
'); ');
......
-- /package/intranet-invoices/sql/oracle/intranet-invoices-create.sql -- /package/intranet-invoices/sql/oracle/intranet-invoices-create.sql
-- --
-- Invoices module for Project/Open -- Copyright (c) 2003-2004 Project/Open
-- --
-- (c) 2003 Frank Bergmann (fraber@fraber.de) -- All rights reserved. Please check
-- http://www.project-open.com/license/ for details.
--
-- @author frank.bergmann@project-open.com
-- Invoices module for Project/Open
-- --
-- Defines: -- Defines:
-- im_invoices Invoice biz object container -- im_invoices Invoice biz object container
-- im_invoice_items Invoice lines -- im_invoice_items Invoice lines
-- im_projects_invoices_map Maps projects -> invoices -- im_projects_invoices_map Maps projects -> invoices
-- im_prices List of prices with defaults
-- --
-- An invoice basically is a container of im_invoice_lines. -- An invoice basically is a container of im_invoice_lines.
...@@ -166,26 +170,22 @@ end im_invoices_audit_tr; ...@@ -166,26 +170,22 @@ end im_invoices_audit_tr;
/ /
show errors show errors
----------------------------------------------------------- -----------------------------------------------------------
-- Invoice Items -- Invoice Items
-- --
-- - Invoice items reflect the very fuzzy structure of invoices, -- - Invoice items reflect the very fuzzy structure of invoices,
-- that may contain basicly everything that fits in one line -- that may contain basicly everything that fits in one line
-- and has a price. -- and has a price.
-- - Invoice items are generated typically from im_tasks, plus -- - Invoice items can created manually or generated from
-- a invoice price, derived(!) from the price list. -- "invoicable items" such as im_trans_tasks or similar.
-- However, all elements (number of units, price, description) -- All fields (number of units, price, description) need to be
-- need to be human editable. -- human editable because invoicing is so messy...
--
-- Tasks and Invoice Items are similar because they both represent
-- substructures of an invoice or a project. However, im_tasks
-- are supposed to be more strongly formalized (type, status, ...),
-- while Invoice Items contain the actually billed price and
-- represent the dirty reality.
-- --
-- Invoicable Tasks and Invoice Items are similar because they
-- both represent substructures of a project or an invoice.
-- However, im_trans_tasks are more formalized (type, status, ...),
-- while Invoice Items contain free text fields, only _derived_
-- from im_trans_tasks and prices. Dirty business world... :-(
create sequence im_invoice_items_seq start with 1; create sequence im_invoice_items_seq start with 1;
create table im_invoice_items ( create table im_invoice_items (
...@@ -225,27 +225,15 @@ create table im_invoice_items ( ...@@ -225,27 +225,15 @@ create table im_invoice_items (
-- particularly if it is a big project. -- particularly if it is a big project.
-- --
-- So there is a N:M relation between these two, and we -- So there is a N:M relation between these two, and we
-- need a mapping table. Also, this table allows us to -- need a mapping table. This table allows us to
-- avoid inserting a "invoice_id" column in the im_projects -- avoid inserting a "invoice_id" column in the im_projects
-- table, thus reducing the dependency between the "core" -- table, thus reducing the dependency between the "core"
-- module and the "invoices" module, allowing for example -- module and the "invoices" module, allowing for example
-- for several different invoices modules. -- for several different invoices modules.
-- --
-- 040403 fraber: We are now using acs_rels instead of
create table im_project_invoice_map ( -- im_project_invoice_map:
project_id integer not null -- acs_rels: object_id_one=project_id, object_id_two=invoice_id
constraint im_proj_inv_map_project
references im_projects,
invoice_id integer not null
constraint im_proj_inv_map_invoice
references im_invoices
);
-- keep the project-invoice-map clean!
create unique index im_project_invoice_map_idx on im_project_invoice_map (
project_id,
invoice_id
);
------------------------------------------------------ ------------------------------------------------------
...@@ -301,80 +289,6 @@ where category_type = 'Intranet Invoice Payment Method'; ...@@ -301,80 +289,6 @@ where category_type = 'Intranet Invoice Payment Method';
-- Procedures -- Procedures
-- --
-- Calculate a match value between a price list item and an invoice_item
-- The higher the match value the better the fit.
create or replace function im_calculate_price_relevancy (
v_price_customer_id IN integer, v_item_customer_id IN integer,
v_price_task_type_id IN integer, v_item_task_type_id IN integer,
v_price_subject_area_id IN integer, v_item_subject_area_id IN integer,
v_price_target_language_id IN integer, v_item_target_language_id IN integer,
v_price_source_language_id IN integer, v_item_source_language_id IN integer
)
RETURN number IS
match_value number;
BEGIN
match_value := 0;
if v_price_task_type_id = v_item_task_type_id then
match_value := match_value + 4;
end if;
if not(v_price_task_type_id is null) and v_price_task_type_id != v_item_task_type_id then
match_value := match_value - 4;
end if;
if v_price_source_language_id = v_item_source_language_id then
match_value := match_value + 3;
end if;
if not(v_price_source_language_id is null) and v_price_source_language_id != v_item_source_language_id then
match_value := match_value - 10;
end if;
if v_price_target_language_id = v_item_target_language_id then
match_value := match_value + 2;
end if;
if not(v_price_target_language_id is null) and v_price_target_language_id != v_item_target_language_id then
match_value := match_value - 10;
end if;
if v_price_subject_area_id = v_item_subject_area_id then
match_value := match_value + 1;
end if;
if not(v_price_subject_area_id is null) and v_price_subject_area_id != v_item_subject_area_id then
match_value := match_value - 10;
end if;
if v_price_customer_id = v_item_customer_id then
match_value := (match_value + 6)*2;
end if;
if v_price_customer_id = 17 then
match_value := match_value + 1;
end if;
if v_price_customer_id != 17 and v_price_customer_id != v_item_customer_id then
match_value := match_value -10;
end if;
return match_value;
END;
/
show errors;
-- Calculate the price for a task_type/customer
create or replace function im_invoice_calculate_price (
v_customer_id IN integer,
v_project_id IN integer,
v_task_type_id IN integer,
v_task_uom_id IN integer
)
RETURN number IS
BEGIN
if v_task_uom_id = 320 then
return 30.00;
end if;
if v_task_uom_id = 324 then
return 0.085;
end if;
return 1.000;
END;
/
show errors;
-- What currency to use?
create or replace function im_invoice_calculate_currency (v_customer_id IN integer) create or replace function im_invoice_calculate_currency (v_customer_id IN integer)
RETURN varchar IS RETURN varchar IS
BEGIN BEGIN
...@@ -635,14 +549,27 @@ begin ...@@ -635,14 +549,27 @@ begin
plugin_name => 'Project Invoice Component', plugin_name => 'Project Invoice Component',
package_name => 'intranet-invoices', package_name => 'intranet-invoices',
page_url => '/intranet/projects/view', page_url => '/intranet/projects/view',
location => 'right', location => 'left',
sort_order => 10,
component_tcl =>
'im_invoices_project_component $project_id'
);
end;
/
-- Show the invoice component in customers page
--
declare
v_plugin integer;
begin
v_plugin := im_component_plugin.new (
plugin_name => 'Customer Invoice Component',
package_name => 'intranet-invoices',
page_url => '/intranet/customers/view',
location => 'left',
sort_order => 10, sort_order => 10,
component_tcl => component_tcl =>
'im_table_with_title "Invoices" \ 'im_invoices_customer_component $customer_id'
[im_invoice_component \
$user_id \
$project_id
]'
); );
end; end;
/ /
......
-- Copyright (C) 1999-2004 ArsDigita, Frank Bergmann and others -- /packages/intranet-invoices/sql/oracle/intranet-invoices-drop.sql
-- --
-- This program is free software. You can redistribute it -- Copyright (C) 2003-2004 Project/Open
-- and/or modify it under the terms of the GNU General --
-- Public License as published by the Free Software Foundation; -- All rights reserved. Please check
-- either version 2 of the License, or (at your option) -- http://www.project-open.com/license/ for details.
-- any later version. This program is distributed in the --
-- hope that it will be useful, but WITHOUT ANY WARRANTY; -- @author frank.bergmann@project-open.com
-- without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU General Public License for more details.
BEGIN BEGIN
...@@ -18,7 +15,7 @@ END; ...@@ -18,7 +15,7 @@ END;
/ /
commit; commit;
delete from im_project_invoice_map; delete from acs_rels r where r.object_id_two in (select invoice_id from im_invoices;)
delete from im_invoice_items; delete from im_invoice_items;
delete from im_invoices; delete from im_invoices;
...@@ -30,7 +27,6 @@ drop sequence im_prices_seq; ...@@ -30,7 +27,6 @@ drop sequence im_prices_seq;
drop sequence im_invoices_seq; drop sequence im_invoices_seq;
drop sequence im_invoice_items_seq; drop sequence im_invoice_items_seq;
drop table im_project_invoice_map;
drop table im_invoice_items; drop table im_invoice_items;
drop table im_invoices_audit; drop table im_invoices_audit;
......
# /tcl/intranet-invoice.tcl # /packages/intranet-invoicing/tcl/intranet-invoice.tcl
#
# Copyright (C) 2003-2004 Project/Open
#
# All rights reserved. Please check
# http://www.project-open.com/license/ for details.
ad_library { ad_library {
Bring together all "components" (=HTML + SQL code) Bring together all "components" (=HTML + SQL code)
related to Invoices related to Invoices
@author fraber@fraber.de @author frank.bergann@project-open.com
@creation-date 27 June 2003
} }
ad_proc -public im_invoices_navbar { default_letter base_url next_page_url prev_page_url export_var_list } { ad_proc -public im_invoices_navbar { default_letter base_url next_page_url prev_page_url export_var_list } {
Returns rendered HTML code for a horizontal sub-navigation Returns rendered HTML code for a horizontal sub-navigation
bar for /intranet-invoices/. bar for /intranet-invoices/.
...@@ -81,7 +84,7 @@ select ...@@ -81,7 +84,7 @@ select
to_char(sysdate, 'YYYY_MM')||'_'|| to_char(sysdate, 'YYYY_MM')||'_'||
trim(to_char(1+max(i.nr),'0000')) as invoice_nr trim(to_char(1+max(i.nr),'0000')) as invoice_nr
from from
(select substr(invoice_nr,9,4) as nr from im_invoices_active (select substr(invoice_nr,9,4) as nr from im_invoices
where substr(invoice_nr, 1,7)=to_char(sysdate, 'YYYY_MM') where substr(invoice_nr, 1,7)=to_char(sysdate, 'YYYY_MM')
UNION UNION
select '0000' as nr from dual select '0000' as nr from dual
...@@ -97,12 +100,28 @@ where ...@@ -97,12 +100,28 @@ where
ascii(substr(i.nr,4,1)) < 58 ascii(substr(i.nr,4,1)) < 58
" "
set invoice_nr [db_string next_invoice_nr $sql -default ""] set invoice_nr [db_string next_invoice_nr $sql -default ""]
ns_log Notice "im_next_invoice_nr: invoice_nr=$invoice_nr"
return $invoice_nr return $invoice_nr
} }
ad_proc im_invoice_component { {customer_id ""} {project_id ""} } { ad_proc im_invoices_customer_component { customer_id } {
Returns a HTML table containing a list of invoices for a particular
customer.
} {
return [im_invoices_base_component $customer_id ""]
}
ad_proc im_invoices_project_component { project_id } {
Returns a HTML table containing a list of invoices for a particular
particular project.
} {
return [im_invoices_base_component "" $project_id]
}
ad_proc im_invoices_base_component { {customer_id ""} {project_id ""} } {
Returns a HTML table containing a list of invoices for a particular Returns a HTML table containing a list of invoices for a particular
customer or a particular project. customer or a particular project.
} { } {
...@@ -172,7 +191,7 @@ order by ...@@ -172,7 +191,7 @@ order by
db_foreach recent_invoices $invoices_sql { db_foreach recent_invoices $invoices_sql {
append invoice_html " append invoice_html "
<tr$bgcolor([expr $ctr % 2])> <tr$bgcolor([expr $ctr % 2])>
<td><A href=/intranet/invoices/view?invoice_id=$invoice_id>$invoice_nr</A></td> <td><A href=/intranet-invoices/view?invoice_id=$invoice_id>$invoice_nr</A></td>
<td>$calculated_due_date</td> <td>$calculated_due_date</td>
<td>$invoice_amount $invoice_currency</td> <td>$invoice_amount $invoice_currency</td>
<td>$payment_amount $payment_currency</td> <td>$payment_amount $payment_currency</td>
...@@ -187,7 +206,7 @@ order by ...@@ -187,7 +206,7 @@ order by
append invoice_html " append invoice_html "
<tr$bgcolor([expr $ctr % 2])> <tr$bgcolor([expr $ctr % 2])>
<td colspan=$colspan> <td colspan=$colspan>
<A HREF=/intranet/invoices/index?status_id=0&[export_url_vars status_id customer_id project_id]> <A HREF=/intranet-invoices/index?status_id=0&[export_url_vars status_id customer_id project_id]>
more invoices... more invoices...
</A> </A>
</td> </td>
...@@ -200,6 +219,29 @@ order by ...@@ -200,6 +219,29 @@ order by
<td colspan=$colspan align=center> <td colspan=$colspan align=center>
<I>No invoices yet for this project</I> <I>No invoices yet for this project</I>
</td> </td>
</tr>\n"
incr ctr
}
if {"" != $customer_id} {
append invoice_html "
<tr>
<td colspan=$colspan align=left>
<A href=/intranet-invoices/new?customer_id=$customer_id>
Create a new invoice from scratch
</A>
</td>
</tr>\n"
}
if {"" != $project_id} {
append invoice_html "
<tr>
<td colspan=$colspan align=left>
<A href=/intranet-invoices/new?project_id=$project_id>
Create a new invoice for this project
</A>
</td>
</tr>\n" </tr>\n"
} }
...@@ -207,7 +249,8 @@ order by ...@@ -207,7 +249,8 @@ order by
return $invoice_html return $invoice_html
} }
ad_proc im_invoice_select { select_name { default "" } { status "" } { exclude_status "" } } {
ad_proc im_invoices_select { select_name { default "" } { status "" } { exclude_status "" } } {
Returns an html select box named $select_name and defaulted to Returns an html select box named $select_name and defaulted to
$default with a list of all the invoices in the system. If status is $default with a list of all the invoices in the system. If status is
......
# /packages/intranet-invoices/www/index.tcl # /packages/intranet-invoices/www/index.tcl
#
# Copyright (C) 2003-2004 Project/Open
#
# All rights reserved. Please check
# http://www.project-open.com/license/ for details.
# --------------------------------------------------------------- # ---------------------------------------------------------------
# 1. Page Contract # 1. Page Contract
...@@ -15,8 +21,7 @@ ad_page_contract { ...@@ -15,8 +21,7 @@ ad_page_contract {
@param start_idx the starting index for query @param start_idx the starting index for query
@param how_many how many rows to return @param how_many how many rows to return
@author mbryzek@arsdigita.com @author frank.bergmann@project-open.com
@cvs-id index.tcl,v 3.24.2.9 2000/09/22 01:38:44 kevin Exp
} { } {
{ order_by "Invoice #" } { order_by "Invoice #" }
{ status_id:integer 0 } { status_id:integer 0 }
...@@ -310,11 +315,6 @@ set filter_html " ...@@ -310,11 +315,6 @@ set filter_html "
set colspan [expr [llength $column_headers] + 1] set colspan [expr [llength $column_headers] + 1]
set table_header_html "" set table_header_html ""
#<tr>
# <td align=center valign=top colspan=$colspan><font size=-1>
# [im_groups_alpha_bar [im_invoice_group_id] $letter "start_idx"]</font>
# </td>
#</tr>"
# Format the header names with links that modify the # Format the header names with links that modify the
# sort order of the SQL query. # sort order of the SQL query.
......
# /www/intranet/invoices/invoice-action.tcl # /packages/intranet-invoices/www/invoice-action.tcl
#
# Copyright (C) 2003-2004 Project/Open
#
# All rights reserved. Please check
# http://www.project-open.com/license/ for details.
ad_page_contract { ad_page_contract {
Purpose: Takes commands from the /intranet/invoices/index Purpose: Takes commands from the /intranet/invoices/index
...@@ -6,6 +12,7 @@ ad_page_contract { ...@@ -6,6 +12,7 @@ ad_page_contract {
@param return_url the url to return to @param return_url the url to return to
@param group_id group id @param group_id group id
@author frank.bergmann@project-open.com
} { } {
return_url:optional return_url:optional
del_invoice:multiple,optional del_invoice:multiple,optional
...@@ -74,8 +81,8 @@ switch $submit { ...@@ -74,8 +81,8 @@ switch $submit {
" "
set delete_map_sql " set delete_map_sql "
delete from im_project_invoice_map m delete from acs_rels r
where m.invoice_id in $invoice_where_list where r.object_id_two in $invoice_where_list
" "
set delete_invoices_sql " set delete_invoices_sql "
......
# /packages/intranet-invoices/www/new-2.tcl
#
# Copyright (C) 2003-2004 Project/Open
#
# All rights reserved. Please check
# http://www.project-open.com/license/ for details.
ad_page_contract {
Purpose: Save invoice changes and set the invoice status to "Created"
or higher.
@author frank.bergmann@project-open.com
} {
invoice_id:integer
{ customer_id:integer 0 }
{ provider_id:integer 0 }
invoice_nr
invoice_date
{ invoice_type_id 700 }
payment_days:integer
payment_method_id:integer
invoice_template_id:integer
vat
tax
item_sort_order:array
item_name:array
item_units:array
item_uom_id:integer,array
item_type_id:integer,array
item_project_id:integer,array
item_rate:array
item_currency:array
{ return_url "/intranet-invoices/" }
}
# ---------------------------------------------------------------
# Defaults & Security
# ---------------------------------------------------------------
set user_id [ad_maybe_redirect_for_registration]
if {![im_permission $user_id view_invoices]} {
ad_return_complaint "Insufficient Privileges" "
<li>You don't have sufficient privileges to see this page."
}
set invoice_status_created [db_string invoice_status "select invoice_status_id from im_invoice_status where upper(invoice_status)='CREATED'"]
set invoice_status_in_process [db_string invoice_status "select category_id from im_categories where category_type='Intranet Invoice Status' and upper(category)='IN PROCESS'"]
set project_status_invoiced [db_string project_status "select category_id from im_categories where category_type='Intranet Project Status' and upper(category)='INVOICED'"]
set customer_internal [db_string customer_internal "select customer_id from im_customers where lower(customer_path) = 'internal'" -default 0]
if {!$customer_internal} {
ad_return_complaint 1 "<li>Unable to find 'Internal' customer with path 'internal'. <br>Maybe somebody has change the path of the customer?"
return
}
if {!$provider_id} { set provider_id $customer_internal }
if {!$customer_id} { set customer_id $customer_internal }
# ---------------------------------------------------------------
# 0. Update invoice base data
# ---------------------------------------------------------------
set invoice_exists_p [db_string invoice_count "select count(*) from im_invoices where invoice_id=:invoice_id"]
if {!$invoice_exists_p} {
db_dml create_invoice "
INSERT INTO im_invoices (
invoice_id,
invoice_nr,
customer_id,
provider_id,
invoice_date,
payment_days,
payment_method_id,
invoice_template_id,
vat,
tax,
invoice_status_id,
invoice_type_id,
last_modified,
last_modifying_user,
modified_ip_address
) VALUES (
:invoice_id,
:invoice_nr,
:customer_id,
:provider_id,
:invoice_date,
:payment_days,
:payment_method_id,
:invoice_template_id,
:vat,
:tax,
:invoice_status_created,
:invoice_type_id,
sysdate,
:user_id,
'[ad_conn peeraddr]'
)"
} else {
db_dml update_im_invoices "
UPDATE im_invoices
SET
invoice_nr=:invoice_nr,
invoice_date=:invoice_date,
payment_days=:payment_days,
payment_method_id=:payment_method_id,
invoice_template_id=:invoice_template_id,
vat=:vat,
tax=:tax
WHERE
invoice_id=:invoice_id
"
}
# ---------------------------------------------------------------
# 1. Create the new "im_invoice_items"
# ---------------------------------------------------------------
# Delete the old items
db_dml delete_invoice_items "
DELETE from im_invoice_items
WHERE invoice_id=:invoice_id
"
set item_list [array names item_name]
foreach nr $item_list {
set name $item_name($nr)
set units $item_units($nr)
set uom_id $item_uom_id($nr)
set type_id $item_type_id($nr)
set project_id $item_project_id($nr)
set rate $item_rate($nr)
set currency $item_currency($nr)
set sort_order $item_sort_order($nr)
ns_log Notice "item($nr, $name, $units, $uom_id, $project_id, $rate, $currency)"
# Insert only if it's not an empty line from the edit screen
if {"" != [string trim $name] || 0 != $units} {
set item_id [db_nextval "im_invoice_items_seq"]
set insert_invoice_items_sql "
INSERT INTO im_invoice_items (
item_id, item_name, project_id, invoice_id, item_units, item_uom_id,
price_per_unit, currency, sort_order, item_type_id, item_status_id, description
) VALUES (
:item_id, :name, :project_id, :invoice_id, :units, :uom_id,
:rate, :currency, :sort_order, :type_id, null, ''
)"
db_dml insert_invoice_items $insert_invoice_items_sql
}
}
# ---------------------------------------------------------------
# Update the invoice status from "In Process" to "Created"
# ---------------------------------------------------------------
# only if
db_dml update_invoice_status "
UPDATE im_invoices set invoice_status_id=:invoice_status_created
WHERE
invoice_id=:invoice_id
and invoice_status_id=:invoice_status_in_process
"
db_release_unused_handles
ad_returnredirect "/intranet-invoices/view?invoice_id=$invoice_id"
# /www/intranet/invoices/new.tcl # /packages/intranet-invoices/www/new.tcl
#
# Copyright (C) 2003-2004 Project/Open
#
# All rights reserved. Please check
# http://www.project-open.com/license/ for details.
# --------------------------------------------------------------- # ---------------------------------------------------------------
# 1. Page Contract # 1. Page Contract
...@@ -7,16 +12,16 @@ ...@@ -7,16 +12,16 @@
ad_page_contract { ad_page_contract {
Receives the list of tasks to invoice, creates a draft invoice Receives the list of tasks to invoice, creates a draft invoice
(status: "In Process") and displays it. (status: "In Process") and displays it.
Provides a button to advance to new-4.tcl, which takes the final Provides a button to advance to new-2.tcl, which takes the final
steps of invoice generation by setting the state of the invoice steps of invoice generation by setting the state of the invoice
to "Created" and the state of the associates im_tasks to "Invoiced". to "Created" and the state of the associates im_tasks to "Invoiced".
@author frank.bergmann@project-open.com @author frank.bergmann@project-open.com
@cvs-id index.tcl,v 3.24.2.9 2000/09/22 01:38:44 kevin Exp
} { } {
{ include_task:multiple "" } { include_task:multiple "" }
{ invoice_id:integer ""} { invoice_id:integer ""}
{ customer_id:integer 0} { customer_id:integer 0}
{ project_id:integer ""}
{ invoice_currency "EUR"} { invoice_currency "EUR"}
{ return_url "/intranet-invoice/"} { return_url "/intranet-invoice/"}
} }
...@@ -47,6 +52,22 @@ set bgcolor(0) " class=roweven" ...@@ -47,6 +52,22 @@ set bgcolor(0) " class=roweven"
set bgcolor(1) " class=rowodd" set bgcolor(1) " class=rowodd"
set required_field "<font color=red size=+1><B>*</B></font>" set required_field "<font color=red size=+1><B>*</B></font>"
# Tricky case: Sombebody has called this page from a project
# So we need to find out the customer of the project and create
# an invoice from scratch, invoicing all project elements.
#
# However, invoices are created in very different ways in
# each business sector:
# - Translation: Sum up the im_trans_tasks and determine the
# price from im_translation_prices.
# - IT: Create invoices from scratch, from hours or from
# (monthly|quarterly|...) service fees
#
if {"" != $project_id} {
set customer_id [db_string customer_id "select customer_id from im_projects where project_id=:project_id"]
}
# --------------------------------------------------------------- # ---------------------------------------------------------------
# 3. Gather invoice data # 3. Gather invoice data
# a: if the invoice already exists # a: if the invoice already exists
...@@ -382,7 +403,7 @@ ns_log Notice "new: before joining the parts together" ...@@ -382,7 +403,7 @@ ns_log Notice "new: before joining the parts together"
set page_body " set page_body "
[im_invoices_navbar "none" "/intranet/invoices/index" "" "" [list]] [im_invoices_navbar "none" "/intranet/invoices/index" "" "" [list]]
<form action=new-4 method=POST> <form action=new-2 method=POST>
[export_form_vars invoice_id return_url] [export_form_vars invoice_id return_url]
<!-- Invoice Data and Customer Tables --> <!-- Invoice Data and Customer Tables -->
......
# /www/intranet/invoices/view.tcl # /packages/intranet-invoices/www/view.tcl
#
# Copyright (C) 2003-2004 Project/Open
#
# All rights reserved. Please check
# http://www.project-open.com/license/ for details.
ad_page_contract { ad_page_contract {
View all the info about a specific project View all the info about a specific project
...@@ -7,10 +12,7 @@ ad_page_contract { ...@@ -7,10 +12,7 @@ ad_page_contract {
in plain HTML format or formatted using an .adp template in plain HTML format or formatted using an .adp template
@param show_all_comments whether to show all comments @param show_all_comments whether to show all comments
@author mbryzek@arsdigita.com @author frank.bergmann@project-open.com
@creation-date Jan 2000
@cvs-id view.tcl,v 3.50.2.17 2000/10/26 20:14:19 tony Exp
} { } {
invoice_id:integer invoice_id:integer
{ show_all_comments 0 } { show_all_comments 0 }
...@@ -213,10 +215,10 @@ select ...@@ -213,10 +215,10 @@ select
p.* p.*
from from
im_projects p, im_projects p,
im_project_invoice_map m acs_rels r
where where
m.invoice_id=:invoice_id r.object_id_one = p.project_id
and m.project_id=p.project_id and r.object_id_two = :invoice_id
" "
db_foreach project_list $project_list_sql { db_foreach project_list $project_list_sql {
...@@ -230,6 +232,17 @@ db_foreach project_list $project_list_sql { ...@@ -230,6 +232,17 @@ db_foreach project_list $project_list_sql {
" "
} }
#append project_list_html "
# <tr>
# <td align=left colspan=2>
# <A href=/intranet-invoices/add-project-to-invoice?invoice_id=$invoice_id>
# Add a project
# </A>
# </td>
# </tr>"
# --------------------------------------------------------------- # ---------------------------------------------------------------
# 3. Select and format Invoice Items # 3. Select and format Invoice Items
# --------------------------------------------------------------- # ---------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment