Commit 354f9098 authored by Frank Bergmann's avatar Frank Bergmann

- moved financial documents to or customers or providers

- started with new-copy
parent 85fe9e38
......@@ -479,13 +479,12 @@ values (31, 'invoice_new', 'view_finance');
--
delete from im_view_columns where column_id > 3000 and column_id < 3099;
--
insert into im_view_columns values (3001,30,NULL,'Invoice #',
insert into im_view_columns values (3001,30,NULL,'Document #',
'"<A HREF=/intranet-invoices/view?invoice_id=$invoice_id>$invoice_nr</A>"',
'','',1,'');
insert into im_view_columns values (3003,30,NULL,'Preview',
'"<A HREF=/intranet-invoices/view?invoice_id=$invoice_id${amp}render_template_id=$invoice_template_id>
$invoice_nr</A>"','','',3,'');
insert into im_view_columns values (3003,30,NULL,'Type',
'$invoice_type','','',3,'');
insert into im_view_columns values (3004,30,NULL,'Provider',
'"<A HREF=/intranet/customers/view?customer_id=$provider_id>$provider_name</A>"',
......@@ -573,8 +572,20 @@ INSERT INTO im_categories VALUES (700,'Customer Invoice','','Intranet Invoice Ty
INSERT INTO im_categories VALUES (702,'Quote','','Intranet Invoice Type','category','t','f');
INSERT INTO im_categories VALUES (704,'Provider Bill','','Intranet Invoice Type','category','t','f');
INSERT INTO im_categories VALUES (706,'Purchase Order','','Intranet Invoice Type','category','t','f');
INSERT INTO im_categories VALUES (708,'Customer Documents','','Intranet Invoice Type','category','t','f');
INSERT INTO im_categories VALUES (710,'Provider Documents','','Intranet Invoice Type','category','t','f');
-- reserved until 799
-- "Customer Invoice" and "Quote" are "Customer Documents"
insert into im_category_hierarchy values (708,700);
insert into im_category_hierarchy values (708,702);
-- "Provider Bills" and "Purchase Orders" are "Provider Documents"
insert into im_category_hierarchy values (710,704);
insert into im_category_hierarchy values (710,706);
-- Invoice Payment Method
delete from im_categories where category_id >= 800 and category_id < 900;
......@@ -684,9 +695,9 @@ begin
-- needs to be the first submenu in order to get selected
v_menu := im_menu.new (
package_name => 'intranet-invoices',
label => 'invoices_list',
name => 'Invoices',
url => '/intranet-invoices/list?invoice_type_id=700',
label => 'invoices_customers',
name => 'Customers',
url => '/intranet-invoices/list?invoice_type_id=708',
sort_order => 10,
parent_menu_id => v_invoices_menu
);
......@@ -699,38 +710,10 @@ begin
v_menu := im_menu.new (
package_name => 'intranet-invoices',
label => 'quote_list',
name => 'Quotes',
url => '/intranet-invoices/list?invoice_type_id=702',
sort_order => 12,
parent_menu_id => v_invoices_menu
);
acs_permission.grant_permission(v_menu, v_admins, 'read');
acs_permission.grant_permission(v_menu, v_senman, 'read');
acs_permission.grant_permission(v_menu, v_accounting, 'read');
acs_permission.grant_permission(v_menu, v_customers, 'read');
acs_permission.grant_permission(v_menu, v_freelancers, 'read');
v_menu := im_menu.new (
package_name => 'intranet-invoices',
label => 'bill_list',
name => 'Provider Bills',
url => '/intranet-invoices/list?invoice_type_id=704',
sort_order => 14,
parent_menu_id => v_invoices_menu
);
acs_permission.grant_permission(v_menu, v_admins, 'read');
acs_permission.grant_permission(v_menu, v_senman, 'read');
acs_permission.grant_permission(v_menu, v_accounting, 'read');
acs_permission.grant_permission(v_menu, v_customers, 'read');
acs_permission.grant_permission(v_menu, v_freelancers, 'read');
v_menu := im_menu.new (
package_name => 'intranet-invoices',
label => 'po_list',
name => 'POs',
url => '/intranet-invoices/list?invoice_type_id=706',
sort_order => 16,
label => 'invoices_providers',
name => 'Providers',
url => '/intranet-invoices/list?invoice_type_id=710',
sort_order => 20,
parent_menu_id => v_invoices_menu
);
acs_permission.grant_permission(v_menu, v_admins, 'read');
......@@ -739,7 +722,6 @@ begin
acs_permission.grant_permission(v_menu, v_customers, 'read');
acs_permission.grant_permission(v_menu, v_freelancers, 'read');
v_menu := im_menu.new (
package_name => 'intranet-invoices',
label => 'invoices_new',
......@@ -757,7 +739,7 @@ end;
commit;
-- Setup the "Invoice New" items for the basic Financial items
-- Setup the "Invoices New" menu for Customer Documents
--
declare
-- Menu IDs
......@@ -784,12 +766,12 @@ begin
select menu_id
into v_invoices_new_menu
from im_menus
where label='invoices_new';
where label='invoices_customers';
v_invoices_menu := im_menu.new (
package_name => 'intranet-invoices',
label => 'new_invoice',
name => 'New Customer Invoice',
label => 'invoices_customers_new_invoice',
name => 'New Customer Invoice from scratch',
url => '/intranet-invoices/new?invoice_type_id=700',
sort_order => 10,
parent_menu_id => v_invoices_new_menu
......@@ -803,10 +785,10 @@ begin
v_invoices_menu := im_menu.new (
package_name => 'intranet-invoices',
label => 'new_invoice_from_quote',
label => 'invoices_customers_new_invoice_from_quote',
name => 'New Customer Invoice from Quote',
url => '/intranet-invoices/new-copy?invoice_type_id=700\&from_invoice_type_id=702',
sort_order => 12,
sort_order => 20,
parent_menu_id => v_invoices_new_menu
);
......@@ -818,10 +800,10 @@ begin
v_invoices_menu := im_menu.new (
package_name => 'intranet-invoices',
label => 'new_quote',
name => 'New Quote',
label => 'invoices_customers_new_quote',
name => 'New Quote from scratch',
url => '/intranet-invoices/new?invoice_type_id=702',
sort_order => 20,
sort_order => 30,
parent_menu_id => v_invoices_new_menu
);
......@@ -831,12 +813,47 @@ begin
acs_permission.grant_permission(v_invoices_menu, v_customers, 'read');
acs_permission.grant_permission(v_invoices_menu, v_freelancers, 'read');
end;
/
commit;
-- Setup the "Invoices New" menu for Customer Documents
--
declare
-- Menu IDs
v_menu integer;
v_invoices_new_menu integer;
v_invoices_menu integer;
-- Groups
v_employees integer;
v_accounting integer;
v_senman integer;
v_customers integer;
v_freelancers integer;
v_proman integer;
v_admins integer;
begin
select group_id into v_admins from groups where group_name = 'P/O Admins';
select group_id into v_senman from groups where group_name = 'Senior Managers';
select group_id into v_accounting from groups where group_name = 'Accounting';
select group_id into v_customers from groups where group_name = 'Customers';
select group_id into v_freelancers from groups where group_name = 'Freelancers';
select menu_id
into v_invoices_new_menu
from im_menus
where label='invoices_providers';
v_invoices_menu := im_menu.new (
package_name => 'intranet-invoices',
label => 'new_bill_from_po',
name => 'New Provider Bill',
label => 'invoices_providers_new_bill',
name => 'New Provider Bill from scratch',
url => '/intranet-invoices/new?invoice_type_id=704',
sort_order => 30,
sort_order => 10,
parent_menu_id => v_invoices_new_menu
);
......@@ -848,10 +865,10 @@ begin
v_invoices_menu := im_menu.new (
package_name => 'intranet-invoices',
label => 'new_bill',
label => 'invoices_providers_new_bill_from_po',
name => 'New Provider Bill from Purchase Order',
url => '/intranet-invoices/new-copy?invoice_type_id=704\&from_invoice_type_id=706',
sort_order => 32,
sort_order => 20,
parent_menu_id => v_invoices_new_menu
);
......@@ -863,10 +880,10 @@ begin
v_invoices_menu := im_menu.new (
package_name => 'intranet-invoices',
label => 'new_po',
name => 'New Purchase Order',
label => 'invoices_providers_new_po',
name => 'New Purchase Order from scratch',
url => '/intranet-invoices/new?invoice_type_id=706',
sort_order => 40,
sort_order => 30,
parent_menu_id => v_invoices_new_menu
);
......
......@@ -29,6 +29,9 @@ ad_proc -public im_invoice_type_invoice {} { return 700 }
ad_proc -public im_invoice_type_quote {} { return 702 }
ad_proc -public im_invoice_type_bill {} { return 704 }
ad_proc -public im_invoice_type_po {} { return 706 }
ad_proc -public im_invoice_type_customer_doc {} { return 708 }
ad_proc -public im_invoice_type_provider_doc {} { return 710 }
# Payment Methods
ad_proc -public im_payment_method_undefined {} { return 800 }
......
......@@ -9,7 +9,7 @@ ad_page_contract {
@param order_by invoice display order
@param include_subinvoices_p whether to include sub invoices
@param status_id criteria for invoice status
@param invoice_status_id criteria for invoice status
@param invoice_type_id criteria for invoice_type_id
@param letter criteria for im_first_letter_default_to_a(ug.group_name)
@param start_idx the starting index for query
......@@ -18,8 +18,8 @@ ad_page_contract {
@author mbryzek@arsdigita.com
@cvs-id index.tcl,v 3.24.2.9 2000/09/22 01:38:44 kevin Exp
} {
{ order_by "Invoice #" }
{ status_id:integer 0 }
{ order_by "Document #" }
{ invoice_status_id:integer 0 }
{ invoice_type_id:integer 0 }
{ customer_id:integer 0 }
{ provider_id:integer 0 }
......@@ -66,8 +66,8 @@ ad_page_contract {
set user_id [ad_maybe_redirect_for_registration]
set current_user_id $user_id
set today [lindex [split [ns_localsqltimestamp] " "] 0]
set page_title "Invoices"
set context_bar [ad_context_bar_ws $page_title]
set page_title "Financial Documents"
set context_bar [ad_context_bar $page_title]
set page_focus "im_header_form.keywords"
set return_url [im_url_with_query]
# Needed for im_view_columns, defined in intranet-views.tcl
......@@ -77,8 +77,8 @@ set local_url "list"
set invoice_status_created [db_string invoice_status "select invoice_status_id from im_invoice_status where upper(invoice_status)='CREATED'"]
if {$status_id == 0} {
set status_id $invoice_status_created
if {$invoice_status_id == 0} {
set invoice_status_id $invoice_status_created
}
......@@ -129,21 +129,28 @@ set status_types [im_memoize_list select_invoice_status_types \
from im_invoice_status
order by lower(invoice_status)"]
# No "All" status, because we _really_ don't want to show the
# "In Process" invoices left over from the creation process.
#
#set status_types [linsert $status_types 0 0 All]
# type_types will be a list of pairs of (invoice_type_id, invoice_type)
set type_types [im_memoize_list select_invoice_type_types \
"select invoice_type_id, invoice_type
from im_invoice_type
order by lower(invoice_type)"]
# ---------------------------------------------------------------
# 5. Generate SQL Query
# ---------------------------------------------------------------
set criteria [list]
if { ![empty_string_p $status_id] && $status_id > 0 } {
lappend criteria "i.invoice_status_id=:status_id"
if { ![empty_string_p $invoice_status_id] && $invoice_status_id > 0 } {
lappend criteria "i.invoice_status_id=:invoice_status_id"
}
if { ![empty_string_p $invoice_type_id] && $invoice_type_id != 0 } {
lappend criteria "i.invoice_type_id=:invoice_type_id"
lappend criteria "i.invoice_type_id in (
select distinct h.child_id
from im_category_hierarchy h
where (child_id=:invoice_type_id or parent_id=:invoice_type_id)
)"
}
if { ![empty_string_p $customer_id] && $customer_id != 0 } {
lappend criteria "i.customer_id=:customer_id"
......@@ -182,7 +189,7 @@ ns_log Notice "/intranet-invoices/index: company_where=$company_where"
set order_by_clause ""
switch $order_by {
"Invoice #" { set order_by_clause "order by invoice_nr" }
"Document #" { set order_by_clause "order by invoice_nr" }
"Preview" { set order_by_clause "order by invoice_nr" }
"Provider" { set order_by_clause "order by provider_name" }
"Client" { set order_by_clause "order by customer_name" }
......@@ -190,6 +197,7 @@ switch $order_by {
"Amount" { set order_by_clause "order by ii.invoice_amount" }
"Paid" { set order_by_clause "order by pa.payment_amount" }
"Status" { set order_by_clause "order by invoice_status_id" }
"Type" { set order_by_clause "order by invoice_type" }
}
set where_clause [join $criteria " and\n "]
......@@ -239,6 +247,7 @@ select
p.customer_name as provider_name,
p.customer_path as provider_short_name,
im_category_from_id(i.invoice_status_id) as invoice_status,
im_category_from_id(i.invoice_type_id) as invoice_type,
sysdate - (i.invoice_date + i.payment_days) as overdue
$extra_select
from
......@@ -288,6 +297,40 @@ if {[string compare $letter "ALL"]} {
set selection "select z.* from ($limited_query) z $order_by_clause"
}
# ---------------------------------------------------------------
# 6a. Format the Filter: Get the admin menu
# ---------------------------------------------------------------
set new_document_menu ""
set parent_menu_label ""
if {$invoice_type_id == [im_invoice_type_customer_doc]} {
set parent_menu_label "invoices_customers"
}
if {$invoice_type_id == [im_invoice_type_provider_doc]} {
set parent_menu_label "invoices_providers"
}
if {"" != $parent_menu_label} {
set parent_menu_sql "select menu_id from im_menus where label=:parent_menu_label"
set parent_menu_id [db_string parent_admin_menu $parent_menu_sql -default ""]
set menu_select_sql "
select m.*
from im_menus m
where parent_menu_id = :parent_menu_id
and acs_permission.permission_p(m.menu_id, :user_id, 'read') = 't'
order by sort_order"
# Start formatting the menu bar
set new_document_menu ""
set ctr 0
db_foreach menu_select $menu_select_sql {
ns_log Notice "im_sub_navbar: menu_name='$name'"
append new_document_menu "<li><a href=\"$url\">$name</a></li>\n"
}
}
# ---------------------------------------------------------------
# 6. Format the Filter
# ---------------------------------------------------------------
......@@ -298,37 +341,55 @@ if {[string compare $letter "ALL"]} {
set filter_html "
<table>
<tr>
<td>
<tr valign=top>
<td valign=top>
<form method=get action='/intranet-invoices/list'>
[export_form_vars start_idx order_by how_many view_name include_subinvoices_p letter]
<table border=0 cellpadding=0 cellspacing=0>
<table border=0 cellpadding=1 cellspacing=1>
<tr>
<td colspan='2' class=rowtitle align=center>
Filter Invoices
Filter Documents
</td>
</tr>
<tr>
<td valign=top>Invoice Status:</td>
<td valign=top>
[im_select status_id $status_types ""]
<td>Document Status:</td>
<td>
[im_select invoice_status_id $status_types ""]
</td>
</tr>
<tr>
<td>Document Type:</td>
<td>
[im_select invoice_type_id $type_types ""]
<input type=submit value=Go name=submit>
</td>
</tr>
</table>
</form>
</td>
<td>
<table><tr>
<td>
<blockquote>
&nbsp;
<blockquote>
</td>
</tr></table>
<td valign=top>&nbsp;</td>
<td valign=top>
<table border=0 cellpadding=1 cellspacing=1>
<tr>
<td colspan='2' class=rowtitle align=center>
New Customer Documents
</td>
</tr>
<tr>
<td colspan=2 valign=top>
<ul>
$new_document_menu
</ul>
</td>
</tr>
</table>
</td>
</tr></table>
</tr>
</table>
"
# ---------------------------------------------------------------
......@@ -480,7 +541,7 @@ set button_html "
set page_body "
$filter_html
[im_invoices_navbar $letter "/intranet-invoices/list" $next_page_url $previous_page_url [list status_id invoice_type_id customer_id start_idx order_by how_many view_name letter]]
[im_invoices_navbar $letter "/intranet-invoices/list" $next_page_url $previous_page_url [list invoice_status_id invoice_type_id customer_id start_idx order_by how_many view_name letter]]
<form action=invoice-action method=POST>
[export_form_vars customer_id invoice_id return_url]
......
......@@ -27,11 +27,8 @@ ad_page_contract {
@author frank.bergmann@project-open.com
} {
{ invoice_id:integer 0}
{ invoice_type_id:integer "[im_invoice_type_invoice]" }
{ from_invoice_type_id:integer "[im_invoice_type_invoice]" }
{ project_id 0 }
{ customer_id 0 }
invoice_id:integer
invoice_type_id:integer
{ return_url "/intranet-invoice/"}
}
......@@ -45,6 +42,20 @@ if {![im_permission $user_id view_invoices]} {
<li>You don't have sufficient privileges to see this page."
}
switch $invoice_type_id {
702 {
set to_invoice_type_id [im_invoice_type_invoice]
}
706 {
set to_invoice_type_id [im_invoice_type_bill]
}
default {
ad_return_complaint 1 "<li>Bad Document Type $invoice_type_id:<br>
We expect either a Quote or a Purchase Order as the document type."
}
}
set todays_date [db_string get_today "select sysdate from dual"]
set page_focus "im_header_form.keywords"
set view_name "invoice_copy"
......@@ -54,38 +65,14 @@ set from_invoice_type_name [db_string invoice_type_name "select im_category_from
set bgcolor(0) " class=roweven"
set bgcolor(1) " class=rowodd"
# 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 {0 != $project_id} {
set customer_id [db_string customer_id "select customer_id from im_projects where project_id=:project_id"]
}
# ---------------------------------------------------------------
# 3. Gather invoice data
# a: if the invoice already exists
# ---------------------------------------------------------------
# Check if we are editing an already existing invoice
# We are editing an already existing invoice
#
if {$invoice_id} {
# We are editing an already existing invoice
#
set invoice_mode "exists"
set button_text "Edit $invoice_type_name"
set page_title "Edit $invoice_type_name"
set context_bar [ad_context_bar [list /intranet/invoices/ "Finance"] $page_title]
db_1row invoices_info_query "
db_1row invoices_info_query "
select
i.*,
im_name_from_user_id(i.customer_contact_id) as customer_contact_name,
......@@ -104,46 +91,20 @@ where
and i.provider_id=p.customer_id(+)
"
# Check if there is a single currency being used in the invoice
# and get it.
# This should always be the case, but doesn't need to...
# Check if there is a single currency being used in the invoice
# and get it.
# This should always be the case, but doesn't need to...
if {"" == $invoice_currency} {
catch {
db_1row invoices_currency_query "
if {"" == $invoice_currency} {
catch {
db_1row invoices_currency_query "
select distinct
currency as invoice_currency
from
im_invoice_items i
where
i.invoice_id=:invoice_id"
} err_msg
}
} else {
# ---------------------------------------------------------------
# Setup the fields for a new invoice
# ---------------------------------------------------------------
# Build the list of selected tasks ready for invoices
set invoice_mode "new"
set in_clause_list [list]
set button_text "New $invoice_type_name"
set page_title "New $invoice_type_name"
set context_bar [ad_context_bar [list /intranet/invoices/ "Finance"] $page_title]
set invoice_id [im_new_object_id]
set invoice_nr [im_next_invoice_nr]
set invoice_status_id [im_invoice_status_created]
set invoice_date $todays_date
set payment_days [ad_parameter -package_id [im_package_invoices_id] "DefaultPaymentDays" "" 30]
set due_date [db_string get_due_date "select sysdate+:payment_days from dual"]
set vat 0
set tax 0
set note ""
set payment_method_id ""
set invoice_template_id ""
} err_msg
}
# ---------------------------------------------------------------
......@@ -157,60 +118,6 @@ if {$invoice_or_quote_p} {
set company_id $provider_id
}
# ---------------------------------------------------------------
# Gather customer data from customer_id (both edit or new modes)
# ---------------------------------------------------------------
db_0or1row invoices_info_query "
select
o.*,
im_email_from_user_id(c.accounting_contact_id) as company_contact_email,
im_name_from_user_id(c.accounting_contact_id) as company_contact_name,
c.customer_name as company_name,
c.customer_path as company_short_name,
cc.country_name company_country_name
from
im_customers c,
im_offices o,
country_codes cc
where
c.customer_id = :customer_id
and c.main_office_id=o.office_id(+)
and o.address_country_code=cc.iso(+)
"
ns_log Notice "after looking up customer #$customer_id"
# ---------------------------------------------------------------
# 7. Select and format the sum of the invoicable items
# for a new invoice
# ---------------------------------------------------------------
if {[string equal $invoice_mode "new"]} {
# start formatting the list of sums with the header...
set task_sum_html "
<tr align=center>
<td class=rowtitle>Order</td>
<td class=rowtitle>Description</td>
<td class=rowtitle>Type</td>
<td class=rowtitle>Units</td>
<td class=rowtitle>UOM</td>
<td class=rowtitle>Rate </td>
</tr>
"
# Start formatting the "reference price list" as well, even though it's going
# to be shown at the very bottom of the page.
#
set price_colspan 11
set ctr 1
set old_project_id 0
set colspan 6
set target_language_id ""
} else {
# ---------------------------------------------------------------
# 8. Get the old invoice items for an already existing invoice
# ---------------------------------------------------------------
......
......@@ -16,6 +16,11 @@ ad_page_contract {
steps of invoice generation by setting the state of the invoice
to "Created" and the state of the associates im_tasks to "Invoiced".
@param create_invoice_from_template
Indicates that "Create Invoice" button was
used to start creating an invoice from a Quote or a
Provider Bill from a Purchase Order
@author frank.bergmann@project-open.com
} {
{ include_task:multiple "" }
......@@ -25,6 +30,7 @@ ad_page_contract {
{ provider_id:integer 0}
{ project_id:integer 0}
{ invoice_currency ""}
{ create_invoice_from_template ""}
{ return_url "/intranet-invoice/"}
}
......@@ -32,6 +38,13 @@ ad_page_contract {
# 2. Defaults & Security
# ---------------------------------------------------------------
# Check if we have to forward to "new-copy":
if {"" != $create_invoice_from_template} {
ad_returnredirect [export_vars -base "new-copy" {invoice_id invoice_type_id}]
ad_script_abort
}
# User id already verified by filters
set user_id [ad_maybe_redirect_for_registration]
if {![im_permission $user_id view_invoices]} {
......
......@@ -500,8 +500,9 @@ if {[exists_and_not_null render_template_id]} {
<form action=new method=POST>
<A HREF=/intranet-invoices/view?[export_url_vars return_url invoice_id render_template_id]>Preview</A>
[export_form_vars return_id invoice_id]
<input type=submit value='Edit'>
[export_form_vars return_id invoice_id invoice_type_id]
<input type=submit name=create_invoice_from_template value='Create Invoice from Quote'>
<input type=submit name=edit_invoice value='Edit'>
</form>
</td>
......
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