Commit dc96170b authored by Frank Bergmann's avatar Frank Bergmann

- fixed some invoice <-> cost issues

- started adding automatic PO generation
parent ba53a886
......@@ -172,6 +172,7 @@ is
invoice_type_id in integer default 700,
payment_method_id in integer default null,
payment_days in integer default 30,
amount in number default 0,
vat in number default 0,
tax in number default 0,
note in varchar default null
......@@ -204,6 +205,7 @@ is
invoice_type_id in integer default 700,
payment_method_id in integer default null,
payment_days in integer default 30,
amount in number,
vat in number default 0,
tax in number default 0,
note in varchar default null
......@@ -226,6 +228,7 @@ is
template_id => invoice_template_id,
effective_date => invoice_date,
payment_days => payment_days,
amount => amount,
currency => invoice_currency,
vat => vat,
tax => tax,
......@@ -833,44 +836,6 @@ end;
/
commit;
-- Show the invoice component in project page
--
declare
v_plugin integer;
begin
v_plugin := im_component_plugin.new (
plugin_name => 'Project Invoice Component',
package_name => 'intranet-invoices',
page_url => '/intranet/projects/view',
location => 'left',
sort_order => 90,
component_tcl =>
'im_invoices_project_component $user_id $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 => 90,
component_tcl =>
'im_invoices_customer_component $user_id $customer_id'
);
end;
/
commit;
-- Add links to edit im_invoices objects...
insert into im_biz_object_urls (object_type, url_type, url) values (
......
......@@ -13,26 +13,6 @@ ad_library {
@author frank.bergann@project-open.com
}
# Frequently used Invoices Stati
ad_proc -public im_invoice_status_in_process {} { return 600 }
ad_proc -public im_invoice_status_created {} { return 602 }
ad_proc -public im_invoice_status_outstanding {} { return 604 }
ad_proc -public im_invoice_status_past_due {} { return 606 }
ad_proc -public im_invoice_status_partially_paid {} { return 608 }
ad_proc -public im_invoice_status_paid {} { return 610 }
ad_proc -public im_invoice_status_deleted {} { return 612 }
ad_proc -public im_invoice_status_filed {} { return 614 }
# Frequently used Invoice Types
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 }
ad_proc -public im_payment_method_cash {} { return 802 }
......@@ -215,196 +195,6 @@ ad_proc im_invoices_object_list_component { user_id invoice_id return_url } {
"
}
ad_proc im_invoices_customer_component { user_id customer_id } {
Returns a HTML table containing a list of invoices for a particular
customer.
} {
return [im_invoices_base_component $user_id $customer_id ""]
}
ad_proc im_invoices_project_component { user_id project_id } {
Returns a HTML table containing a list of invoices for a particular
particular project.
} {
return [im_invoices_base_component $user_id "" $project_id]
}
ad_proc im_invoices_base_component { user_id {customer_id ""} {project_id ""} } {
Returns a HTML table containing a list of invoices for a particular
customer or a particular project.
} {
if {![im_permission $user_id view_invoices]} {
return ""
}
set bgcolor(0) " class=roweven "
set bgcolor(1) " class=rowodd "
set max_invoices 5
set colspan 5
# ----------------- Compose SQL Query --------------------------------
set where_conds [list]
if {"" != $customer_id} { lappend where_conds "i.customer_id=:customer_id" }
if {"" != $project_id} {
# Select the invoice_id's of invoice_items and
# invoices explicitely associated with a project.
lappend where_conds "
i.invoice_id in (
select distinct invoice_id
from im_invoice_items
where project_id=:project_id
UNION
select distinct object_id_two as invoice_id
from acs_rels
where object_id_one = :project_id
)"
}
set where_clause [join $where_conds "\n and "]
if {"" == $where_clause} { set where_clause "1=1" }
set invoices_sql "
select
i.*,
ii.invoice_amount,
ii.invoice_currency,
pa.payment_amount,
pa.payment_currency,
im_category_from_id(i.invoice_status_id) as invoice_status,
im_category_from_id(i.invoice_type_id) as invoice_type,
i.invoice_date + payment_days as calculated_due_date
from
im_invoices i,
(select
invoice_id,
sum(item_units * price_per_unit) as invoice_amount,
max(currency) as invoice_currency
from im_invoice_items
group by invoice_id
) ii,
(select
sum(amount) as payment_amount,
max(currency) as payment_currency,
invoice_id
from im_payments
group by invoice_id
) pa
where
$where_clause
and i.invoice_status_id not in ([im_invoice_status_in_process])
and i.invoice_id=ii.invoice_id(+)
and i.invoice_id=pa.invoice_id(+)
order by
invoice_nr desc
"
set invoice_html "
<table border=0>
<tr>
<td colspan=$colspan class=rowtitle align=center>
Financial Documents
</td>
</tr>
<tr class=rowtitle>
<td align=center class=rowtitle>Document</td>
<td align=center class=rowtitle>Type</td>
<td align=center class=rowtitle>Due</td>
<td align=center class=rowtitle>Amount</td>
<td align=center class=rowtitle>Paid</td>
</tr>
"
set ctr 1
db_foreach recent_invoices $invoices_sql {
append invoice_html "
<tr$bgcolor([expr $ctr % 2])>
<td><A href=/intranet-invoices/view?invoice_id=$invoice_id>$invoice_nr</A></td>
<td>$invoice_type</td>
<td>$calculated_due_date</td>
<td>$invoice_amount $invoice_currency</td>
<td>$payment_amount $payment_currency</td>
</tr>\n"
incr ctr
if {$ctr > $max_invoices} { break }
}
if {$ctr > $max_invoices} {
append invoice_html "
<tr$bgcolor([expr $ctr % 2])>
<td colspan=$colspan>
<A HREF=/intranet-invoices/index?status_id=0&[export_url_vars status_id customer_id project_id]>
more invoices...
</A>
</td>
</tr>\n"
}
if {$ctr == 1} {
append invoice_html "
<tr$bgcolor([expr $ctr % 2])>
<td colspan=$colspan align=center>
<I>No financial documents yet for this project</I>
</td>
</tr>\n"
incr ctr
}
if {"" != $customer_id && "" == $project_id} {
append invoice_html "
<tr>
<td colspan=$colspan align=left>
<!-- <A href=/intranet-invoices/new?customer_id=$customer_id>
Create a new invoice for this customer
</A>
-->
</td>
</tr>\n"
}
if {"" != $project_id} {
append invoice_html "
<tr>
<td colspan=$colspan align=left>
<A href=/intranet-invoices/index?project_id=$project_id>
Create a new document for this project
</A>
</td>
</tr>\n"
}
if {"" != $customer_id} {
append invoice_html "
<tr>
<td colspan=$colspan align=right>
<A href=/intranet-invoices/index?customer_id=$customer_id>
Create a new document for this customer
</A>
</td>
</tr>\n"
}
append invoice_html "</table>\n"
return $invoice_html
}
ad_proc -public im_invoice_type_select { select_name { default "" } } {
Returns an html select box named $select_name and defaulted to
$default with a list of all the invoice_types in the system
} {
return [im_category_select "Intranet Invoice Type" $select_name $default]
}
ad_proc -public im_invoice_status_select { select_name { default "" } } {
Returns an html select box named $select_name and defaulted to
$default with a list of all the invoice status_types in the system
} {
return [im_category_select "Intranet Invoice Status" $select_name $default]
}
ad_proc im_invoice_payment_method_select { select_name { default "" } } {
Returns an html select box named $select_name and defaulted to $default
with a list of all the partner statuses in the system
......@@ -412,13 +202,6 @@ ad_proc im_invoice_payment_method_select { select_name { default "" } } {
return [im_category_select "Intranet Invoice Payment Method" $select_name $default]
}
ad_proc im_invoice_template_select { select_name { default "" } } {
Returns an html select box named $select_name and defaulted to $default
with a list of all the partner statuses in the system
} {
return [im_category_select "Intranet Invoice Template" $select_name $default]
}
ad_proc im_invoices_select { select_name { default "" } { status "" } { exclude_status "" } } {
Returns an html select box named $select_name and defaulted to
......@@ -442,17 +225,17 @@ where
if { ![empty_string_p $status] } {
ns_set put $bind_vars status $status
append sql " and invoice_status_id=(select invoice_status_id from im_invoice_status where invoice_status=:status)"
append sql " and cost_status_id=(select cost_status_id from im_cost_status where cost_status=:status)"
}
if { ![empty_string_p $exclude_status] } {
set exclude_string [im_append_list_to_ns_set $bind_vars invoice_status_type $exclude_status]
append sql " and invoice_status_id in (select invoice_status_id
from im_invoice_status
where invoice_status not in ($exclude_string)) "
set exclude_string [im_append_list_to_ns_set $bind_vars cost_status_type $exclude_status]
append sql " and cost_status_id in (select cost_status_id
from im_cost_status
where cost_status not in ($exclude_string)) "
}
append sql " order by lower(invoice_nr)"
return [im_selection_to_select_box $bind_vars "invoice_status_select" $sql $select_name $default]
return [im_selection_to_select_box $bind_vars "cost_status_select" $sql $select_name $default]
}
......
......@@ -81,28 +81,31 @@ if {"" != $del_action && [info exists object_ids]} {
append query "
select
i.*,
ci.*,
c.*,
o.*,
i.invoice_date + i.payment_days as calculated_due_date,
ci.effective_date + ci.payment_days as calculated_due_date,
pm_cat.category as invoice_payment_method,
pm_cat.category_description as invoice_payment_method_desc,
im_name_from_user_id(c.accounting_contact_id) as customer_contact_name,
im_email_from_user_id(c.accounting_contact_id) as customer_contact_email,
c.customer_name,
cc.country_name,
im_category_from_id(i.invoice_status_id) as invoice_status,
im_category_from_id(i.invoice_type_id) as invoice_type,
im_category_from_id(i.invoice_template_id) as invoice_template
im_category_from_id(ci.cost_status_id) as cost_status,
im_category_from_id(ci.cost_type_id) as cost_type,
im_category_from_id(ci.template_id) as invoice_template
from
im_invoices i,
im_costs ci,
im_customers c,
im_offices o,
country_codes cc,
im_categories pm_cat
where
i.invoice_id=:invoice_id
i.invoice_id = :invoice_id
and i.invoice_id = ci.cost_id
and i.payment_method_id=pm_cat.category_id(+)
and i.customer_id=c.customer_id(+)
and ci.customer_id=c.customer_id(+)
and c.main_office_id=o.office_id(+)
and o.address_country_code=cc.iso(+)
"
......
......@@ -222,11 +222,11 @@ if { [db_table_exists im_payments] } {
(select
sum(amount) as payment_amount,
max(currency) as payment_currency,
cost_item_id
cost_id
from im_payments
group by cost_item_id
group by cost_id
) pa\n"
append extra_where "and i.invoice_id=pa.cost_item_id(+)\n"
append extra_where "and i.invoice_id=pa.cost_id(+)\n"
}
# -----------------------------------------------------------------
......
......@@ -19,11 +19,11 @@ ad_page_contract {
{ project_id:integer 0 }
invoice_nr
invoice_date
{ invoice_status_id "[im_invoice_status_created]" }
{ invoice_type_id "[im_invoice_type_invoice]" }
{ cost_status_id "[im_cost_status_created]" }
cost_type_id
payment_days:integer
{ payment_method_id:integer "" }
invoice_template_id:integer
template_id:integer
vat
tax
item_sort_order:array
......@@ -42,11 +42,11 @@ ad_page_contract {
# ---------------------------------------------------------------
# Invoices and Quotes have a "Customer" fields.
set invoice_or_quote_p [expr $invoice_type_id == [im_invoice_type_invoice] || $invoice_type_id == [im_invoice_type_quote]]
set invoice_or_quote_p [expr $cost_type_id == [im_cost_type_invoice] || $cost_type_id == [im_cost_type_quote]]
ns_log Notice "intranet-invoices/new-2: invoice_or_quote_p=$invoice_or_quote_p"
# Invoices and Bills have a "Payment Terms" field.
set invoice_or_bill_p [expr $invoice_type_id == [im_invoice_type_invoice] || $invoice_type_id == [im_invoice_type_bill]]
set invoice_or_bill_p [expr $cost_type_id == [im_cost_type_invoice] || $cost_type_id == [im_cost_type_bill]]
ns_log Notice "intranet-invoices/new-2: invoice_or_bill_p=$invoice_or_bill_p"
if {$invoice_or_quote_p} {
......@@ -104,10 +104,11 @@ BEGIN
provider_id => :provider_id,
invoice_date => sysdate,
invoice_template_id => :invoice_template_id,
invoice_status_id => :invoice_status_id,
invoice_type_id => :invoice_type_id,
cost_status_id => :cost_status_id,
cost_type_id => :cost_type_id,
payment_method_id => :payment_method_id,
payment_days => :payment_days,
amount => 0,
vat => :vat,
tax => :tax
);
......@@ -153,5 +154,22 @@ INSERT INTO im_invoice_items (
}
}
# ---------------------------------------------------------------
# Update the invoice amount based on the invoice items
# ---------------------------------------------------------------
set update_invoice_amount_sql "
update im_costs
set amount = (
select sum(price_per_unit * item_units)
from im_invoice_items
where invoice_id = :invoice_id
group by invoice_id
)
where cost_id = :invoice_id
"
db_dml update_invoice_amount $update_invoice_amount_sql
db_release_unused_handles
ad_returnredirect "/intranet-invoices/view?invoice_id=$invoice_id"
......@@ -16,17 +16,17 @@
<table border=0 cellPadding=0 cellspacing=2 width=100%>
<tr><td align=middle class=rowtitle colspan=2>@invoice_type@ Data</td></tr>
<tr><td align=middle class=rowtitle colspan=2>@cost_type@ Data</td></tr>
<tr>
<td class=rowodd>@invoice_type@ nr.:</td>
<td class=rowodd>@cost_type@ nr.:</td>
<td class=rowodd>
<input type=text name=invoice_nr size=15 value='@invoice_nr@'>
</td>
</tr>
<tr>
<td class=roweven>@invoice_type@ date:</td>
<td class=roweven>@cost_type@ date:</td>
<td class=roweven>
<input type=text name=invoice_date size=15 value='@invoice_date@'>
<input type=text name=invoice_date size=15 value='@effective_date@'>
</td>
</tr>
<tr>
......@@ -42,15 +42,15 @@
</tr>
</if>
<tr>
<td class=roweven> @invoice_type@ template:</td>
<td class=roweven> @cost_type@ template:</td>
<td class=roweven>@template_select;noquote@</td>
</tr>
<tr>
<td class=rowodd>@invoice_type@ status</td>
<td class=rowodd>@cost_type@ status</td>
<td class=rowodd>@status_select;noquote@</td>
</tr>
<tr>
<td class=roweven>@invoice_type@ type</td>
<td class=roweven>@cost_type@ type</td>
<td class=roweven>@type_select;noquote@</td>
</tr>
......
......@@ -25,7 +25,7 @@ ad_page_contract {
} {
{ include_task:multiple "" }
{ invoice_id:integer 0}
{ invoice_type_id:integer "[im_invoice_type_invoice]" }
{ cost_type_id:integer "[im_cost_type_invoice]" }
{ customer_id:integer 0}
{ provider_id:integer 0}
{ project_id:integer 0}
......@@ -40,7 +40,7 @@ ad_page_contract {
# 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_returnredirect [export_vars -base "new-copy" {invoice_id cost_type_id}]
ad_script_abort
}
......@@ -90,17 +90,17 @@ if {$invoice_id} {
db_1row invoices_info_query "
select
i.invoice_nr,
i.customer_id,
i.provider_id,
i.invoice_date,
i.payment_days,
i.vat,
i.tax,
ci.customer_id,
ci.provider_id,
ci.effective_date,
ci.payment_days,
ci.vat,
ci.tax,
i.payment_method_id,
i.invoice_template_id,
i.invoice_status_id,
i.invoice_type_id,
im_category_from_id(i.invoice_type_id) as invoice_type,
ci.template_id,
ci.cost_status_id,
ci.cost_type_id,
im_category_from_id(ci.cost_type_id) as cost_type,
im_name_from_user_id(i.customer_contact_id) as customer_contact_name,
im_email_from_user_id(i.customer_contact_id) as customer_contact_email,
c.customer_name as customer_name,
......@@ -109,16 +109,19 @@ select
p.customer_path as provider_short_name
from
im_invoices i,
im_costs ci,
im_customers c,
im_customers p
where
i.invoice_id=:invoice_id
and i.customer_id=c.customer_id(+)
and i.provider_id=p.customer_id(+)"
and ci.customer_id=c.customer_id(+)
and ci.provider_id=p.customer_id(+)
and i.invoice_id = ci.cost_id
"
set invoice_mode "exists"
set button_text "Edit $invoice_type"
set page_title "Edit $invoice_type"
set button_text "Edit $cost_type"
set page_title "Edit $cost_type"
set context_bar [ad_context_bar [list /intranet/invoices/ "Finance"] $page_title]
# Check if there is a single currency being used in the invoice
......@@ -143,22 +146,22 @@ where
# Build the list of selected tasks ready for invoices
set invoice_mode "new"
set in_clause_list [list]
set invoice_type [db_string invoice_type "select im_category_from_id(:invoice_type_id) from dual"]
set button_text "New $invoice_type"
set page_title "New $invoice_type"
set cost_type [db_string cost_type "select im_category_from_id(:cost_type_id) from dual"]
set button_text "New $cost_type"
set page_title "New $cost_type"
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 cost_status_id [im_cost_status_created]
set effective_date $todays_date
set payment_days [ad_parameter -package_id [im_package_cost_id] "DefaultCustomerInvoicePaymentDays" "" 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 ""
set template_id ""
}
if {"" == $invoice_currency} {
......@@ -171,10 +174,10 @@ if {"" == $invoice_currency} {
# ---------------------------------------------------------------
# Invoices and Quotes have a "Customer" fields.
set invoice_or_quote_p [expr $invoice_type_id == [im_invoice_type_invoice] || $invoice_type_id == [im_invoice_type_quote]]
set invoice_or_quote_p [expr $cost_type_id == [im_cost_type_invoice] || $cost_type_id == [im_cost_type_quote]]
# Invoices and Bills have a "Payment Terms" field.
set invoice_or_bill_p [expr $invoice_type_id == [im_invoice_type_invoice] || $invoice_type_id == [im_invoice_type_bill]]
set invoice_or_bill_p [expr $cost_type_id == [im_cost_type_invoice] || $cost_type_id == [im_cost_type_bill]]
if {$invoice_or_quote_p} {
set company_id $customer_id
......@@ -188,9 +191,9 @@ if {$invoice_or_quote_p} {
# ---------------------------------------------------------------
set payment_method_select [im_invoice_payment_method_select payment_method_id $payment_method_id]
set template_select [im_invoice_template_select invoice_template_id $invoice_template_id]
set status_select [im_invoice_status_select invoice_status_id $invoice_status_id]
set type_select [im_invoice_type_select invoice_type_id $invoice_type_id]
set template_select [im_invoice_template_select template_id $template_id]
set status_select [im_invoice_status_select cost_status_id $cost_status_id]
set type_select [im_invoice_type_select cost_type_id $cost_type_id]
set customer_select [im_customer_select customer_id $customer_id "" "Customer"]
set provider_select [im_customer_select provider_id $provider_id "" "Provider"]
......
......@@ -104,6 +104,7 @@ ad_proc im_format_cur { cur {min_decimals ""} {max_decimals ""} } {
append query "
select
i.*,
ci.*,
c.*,
o.*,
i.invoice_date + i.payment_days as calculated_due_date,
......@@ -113,17 +114,19 @@ select
im_email_from_user_id(c.accounting_contact_id) as customer_contact_email,
c.customer_name,
cc.country_name,
im_category_from_id(i.invoice_status_id) as invoice_status,
im_category_from_id(i.invoice_type_id) as invoice_type,
im_category_from_id(i.invoice_template_id) as invoice_template
im_category_from_id(ci.cost_status_id) as cost_status,
im_category_from_id(ci.cost_type_id) as cost_type,
im_category_from_id(ci.template_id) as invoice_template
from
im_invoices_active i,
im_costs ci,
im_customers c,
im_offices o,
country_codes cc,
im_categories pm_cat
where
i.invoice_id=:invoice_id
and ci.cost_id = i.invoice_id
and i.payment_method_id=pm_cat.category_id(+)
and i.customer_id=c.customer_id(+)
and c.main_office_id=o.office_id(+)
......@@ -135,7 +138,7 @@ if { ![db_0or1row projects_info_query $query] } {
return
}
set page_title "One $invoice_type"
set page_title "One $cost_type"
set context_bar [ad_context_bar [list /intranet-invoices/ "Finance"] $page_title]
......@@ -144,17 +147,17 @@ set context_bar [ad_context_bar [list /intranet-invoices/ "Finance"] $page_title
# ---------------------------------------------------------------
set invoice_data_html "
<tr><td align=middle class=rowtitle colspan=2>$invoice_type Data</td></tr>
<tr><td align=middle class=rowtitle colspan=2>$cost_type Data</td></tr>
<tr>
<td class=rowodd>$invoice_type nr.:</td>
<td class=rowodd>$cost_type nr.:</td>
<td class=rowodd>$invoice_nr</td>
</tr>
<tr>
<td class=roweven>$invoice_type date:</td>
<td class=roweven>$cost_type date:</td>
<td class=roweven>$invoice_date</td>
</tr>
<!-- <tr>
<td class=rowodd>$invoice_type due date:</td>
<td class=rowodd>$cost_type due date:</td>
<td class=rowodd>$due_date</td>
</tr>
-->
......@@ -167,12 +170,12 @@ set invoice_data_html "
<td class=rowodd>$invoice_payment_method</td>
</tr>
<tr>
<td class=roweven> $invoice_type template:</td>
<td class=roweven> $cost_type template:</td>
<td class=roweven>$invoice_template</td>
</tr>
<tr>
<td class=roweven> $invoice_type type:</td>
<td class=roweven>$invoice_type</td>
<td class=roweven> $cost_type type:</td>
<td class=roweven>$cost_type</td>
</tr>
"
......@@ -283,7 +286,7 @@ select
from
im_payments p
where
p.invoice_id = :invoice_id
p.cost_id = :invoice_id
"
set payment_ctr 0
......@@ -461,8 +464,8 @@ if {[exists_and_not_null render_template_id]} {
append invoice_template_path [db_string sel_invoice "select category from im_categories where category_id=:render_template_id"]
if {![file isfile $invoice_template_path] || ![file readable $invoice_template_path]} {
ad_return_complaint "Unknown $invoice_type Template" "
<li>$invoice_type template '$invoice_template_path' doesn't exist or is not readable
ad_return_complaint "Unknown $cost_type Template" "
<li>$cost_type template '$invoice_template_path' doesn't exist or is not readable
for the web server. Please notify your system administrator."
return
}
......@@ -479,7 +482,7 @@ if {[exists_and_not_null render_template_id]} {
# No render template defined - render using default html style
set page_body "
[im_invoices_navbar "none" "/intranet-invoices/index" "" "" [list]]
[im_costs_navbar "none" "/intranet-invoices/index" "" "" [list]""]
<!-- Invoice Data and Receipient Tables -->
......@@ -500,7 +503,7 @@ 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 invoice_type_id]
[export_form_vars return_id invoice_id cost_type_id]
<input type=submit name=create_invoice_from_template value='Create Invoice from Quote'>
<input type=submit name=edit_invoice value='Edit'>
</form>
......
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