Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f4ddb65
Implement logic for creating a new incoming invoice
mladjo2505 Feb 25, 2016
baf4897
Fix tabindex on invoicein edit page
mladjo2505 Mar 16, 2016
628e3ea
Add unit price with tax to invoice lines in invoicein edit view
mladjo2505 Mar 16, 2016
4f08acb
Calculate total invoice amount on save for manually created invoices
mladjo2505 Mar 16, 2016
2ebe98c
Rename migration to next available number
mladjo2505 Mar 16, 2016
42ce21e
Add migration for clearing unit price with tax to 0
mladjo2505 Mar 17, 2016
af7fd7e
Fix invoicein import from fakturabank
mladjo2505 Mar 17, 2016
2386e62
Fix calculating invoice total amount
mladjo2505 Mar 17, 2016
e00d854
Do not show the JournalID for the invoices that cannot be bookkept
mladjo2505 Mar 17, 2016
e293baa
Show project and department names as well on invoicein list page
mladjo2505 Mar 17, 2016
7d5d7d5
Show who created the invoice and when if it was not imported
mladjo2505 Mar 17, 2016
7dbd255
Update invoicein fields correctly on date/supplier change
mladjo2505 Mar 17, 2016
33f5b87
Small fixes after codereview
mladjo2505 Mar 29, 2016
737d86b
Fix: Just print invoicein total amount, resolve missing accountplan
mladjo2505 Apr 4, 2016
35b1231
Fix after code review and discussion
mladjo2505 Jun 2, 2016
c98dca4
Small fixes after code review
mladjo2505 Jun 20, 2016
542c125
Fix typos on invoicein.edit page
mladjo2505 Jul 29, 2016
a93e7c0
Fix more stuff
mladjo2505 Jul 29, 2016
d4c2df6
Add invoice date validation to incoming invoice
mladjo2505 Aug 15, 2016
ce3f06b
Payment means should be printed as text
mladjo2505 Aug 15, 2016
a87998c
Fix for missing accountplan id for invoice in lines
mladjo2505 Aug 15, 2016
b8eed81
Recalculate invoice on save and delete
mladjo2505 Aug 17, 2016
49952c5
Add warning errors to invoice incoming
mladjo2505 Aug 17, 2016
070abd1
Remove more remittance stuff
mladjo2505 Aug 17, 2016
71bd82b
Additional fixes after code review
mladjo2505 Sep 8, 2016
ee52e7e
Fix invoicein show after rebase
mladjo2505 Dec 7, 2016
9bb74fe
Fix recalculate on save an some alignment on edit page
mladjo2505 Feb 8, 2017
4a3044d
Renumber migration
mladjo2505 Apr 26, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions db/changes/175_imported_to_invoicein_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Add imported to invoicein
ALTER TABLE invoicein
ADD Imported int(1) DEFAULT 1;

UPDATE invoiceinline SET UnitCostPrice = 0 WHERE Active = 1;
4 changes: 4 additions & 0 deletions inc/top.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@
<a href="<? print $_lib['sess']->dispatch ?>t=journal.edit&new=1&type=bank_out&voucher_AccountPlanID=<? print $setup['bankut']; ?>" class="group_buy">Ut</a>
<a href="<? print $_lib['sess']->dispatch ?>t=ocr.list">Innbetaling (OCR/KID)</a>
<a href="<? print $_lib['sess']->dispatch ?>t=bank.list">Bank</a>
<?
/* Commented out per Arnt's instructions
<a href="<? print $_lib['sess']->dispatch ?>t=remittance.listincoming">Betaling/Remittering</a>
*/
?>
</fieldset>
</td>
<td>
Expand Down
23 changes: 23 additions & 0 deletions modules/department/model/department.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?

class lodo_department {

public function __construct($args) {
foreach($args as $key => $value) {
$this->{$key} = $value;
}
}

public function getDepartmentIDAndName() {
global $_lib;
if (isset($this->DepartmentID)) {
$query_department = sprintf("SELECT * FROM department WHERE DepartmentID = %d", $this->DepartmentID);
$department_row = $_lib['storage']->get_row(array('query' => $query_department));
$department_id_and_name = $department_row->DepartmentID . " - " . $department_row->DepartmentName;
return $department_id_and_name;
} else {
return "";
}
}
}
?>
12 changes: 9 additions & 3 deletions modules/fakturabank/model/fakturabank.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1643,7 +1643,7 @@ public function registerincoming() {

#Foreign currency
if ($is_foreign) {
$datalineH['UnitCostPrice'] = exchange::convertToLocal($InvoiceO->DocumentCurrencyCode, $CustPrice);
$datalineH['UnitCustPrice'] = exchange::convertToLocal($InvoiceO->DocumentCurrencyCode, $CustPrice);
$datalineH['ForeignCurrencyID'] = $InvoiceO->DocumentCurrencyCode;
$datalineH['ForeignAmount'] = (float)$line->LineExtensionAmount + $line->TaxTotal->TaxAmount;
$datalineH['ForeignConvRate'] = $conversion_rate;
Expand All @@ -1655,8 +1655,6 @@ public function registerincoming() {
$datalineH['TaxAmount'] = (float)$line->TaxTotal->TaxAmount;
}

$datalineH['UnitCustPrice'] = $datalineH['UnitCostPrice'];

$datalineH['UnitCostPriceCurrencyID'] = exchange::getLocalCurrency();
$datalineH['UnitCustPriceCurrencyID'] = exchange::getLocalCurrency();

Expand All @@ -1665,6 +1663,14 @@ public function registerincoming() {

$datalineH['TotalWithTax'] = $datalineH['TotalWithoutTax'] + $datalineH['TaxAmount'];

// If Quantity not zero, we can devide by it and get the tax amount per unit. If not then set the amount of
// one unit with tax to 100 + Vat percent of the amount of one unit without tax
if ($Quantity != 0) {
$datalineH['UnitCostPrice'] = $datalineH['UnitCustPrice'] + $datalineH['TaxAmount']/$Quantity;
} else {
$datalineH['UnitCostPrice'] = $datalineH['UnitCustPrice'] * (1 + $datalineH['Vat']/100.0);
}

$datalineH['InsertedByPersonID']= $_lib['sess']->get_person('PersonID');
$datalineH['InsertedDateTime'] = $_lib['sess']->get_session('Datetime');
$datalineH['UpdatedByPersonID'] = $_lib['sess']->get_person('PersonID');
Expand Down
2 changes: 1 addition & 1 deletion modules/invoice/view/listoutgoing.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
<? print $_lib['form3']->submit(array('name' => 'action_auto_save','value' => "Lagre dato")) ?>
<?
$valid_accountperiod = $accounting->is_valid_accountperiod($invoice_period, $_lib['sess']->get_person('AccessLevel'));
$valid_date = validDate($voucher_date);
$valid_date = $_lib['validation']->date($voucher_date);
if ($valid_accountperiod && $valid_date) {
list($nextJournalID, $nextMessage) = $accounting->get_next_available_journalid(array('type'=>'S', 'available' => true));
echo ' fakturanummer: ' . $nextJournalID;
Expand Down
10 changes: 2 additions & 8 deletions modules/invoice/view/record.inc
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
<?

// recieves date as string 'YYYY-MM-DD' and returns bool if date is valid
function validDate($date) {
$d = DateTime::createFromFormat('Y-m-d', $date);
return $d && $d->format('Y-m-d') === $date;
}

$CustomerAccountPlanID = (int) $_POST["invoiceout_CustomerAccountPlanID_$InvoiceID"];
if ($CustomerAccountPlanID == 0 && $InvoiceID) {
$CustomerAccountPlanID = $_lib['storage']->get_row(array('query' => 'SELECT CustomerAccountPlanID FROM invoiceout WHERE InvoiceID = ' . $InvoiceID))->CustomerAccountPlanID;
Expand All @@ -31,7 +25,7 @@ if($_lib['input']->getProperty('action_invoice_update') or $_lib['input']->getPr
}

$invoice_date = $_POST['invoiceout_InvoiceDate_'.$InvoiceID];
if (!validDate($invoice_date)) {
if (!$_lib['validation']->date($invoice_date)) {
$_lib['message']->add('Ugyldig fakturadato '.$invoice_date.'!');
} else {
$updated = false;
Expand Down Expand Up @@ -78,7 +72,7 @@ elseif($_lib['input']->getProperty('action_auto_save')) {
$message = "";
$voucher_periode = $_POST['voucher_period'];
}
if (validDate($_POST['voucher_date'])) {
if ($_lib['validation']->date($_POST['voucher_date'])) {
$voucher_date = $_POST['voucher_date'];
} else {
$voucher_date = "0000-00-00";
Expand Down
166 changes: 162 additions & 4 deletions modules/invoicein/model/invoicein.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ function fill($args) {
if($this->ToDate) {
$query .= " i.InvoiceDate <= '$this->ToDate' and ";
}
if($this->ID) {
$query .= " i.ID = '$this->ID' and ";
}
if($this->PaymentMeans) {
$query .= " i.PaymentMeans = '$this->PaymentMeans' and ";
}
Expand Down Expand Up @@ -120,7 +123,6 @@ function fill($args) {
$row->Status .= "Er allerede bilagsf&oslash;rt";

} else {
$row->JournalID = $NextAvailableJournalID++;
$row->Journal = true;
$row->Class = 'green';
}
Expand Down Expand Up @@ -167,6 +169,12 @@ function fill($args) {
$row->Class = 'red';
}

if ($row->TotalCustPrice == 0) {
$row->Status .= "Faktura med bel&oslash;p 0";
$row->Journal = false;
}

if (!$row->Journaled && $row->Journal) $row->JournalID = $NextAvailableJournalID++;
$row->VoucherType = $this->VoucherType;
$this->iteratorH[] = $row;
}
Expand Down Expand Up @@ -286,7 +294,12 @@ function update($args) {

$ID = $args['ID'];
$AccountPlanID = $args['invoicein_SupplierAccountPlanID_' . $ID];
$accountplan = $accounting->get_accountplan_object($AccountPlanID);
if (!is_numeric($AccountPlanID)) {
$_lib['message']->add('Leverand&oslash;r ikke valgt!');
$accountplan = NULL;
} else {
$accountplan = $accounting->get_accountplan_object($AccountPlanID);
}
$invoicein = $_lib['storage']->get_row(array('query' => "select * from invoicein where ID='$ID'"));

self::addVATPercentToAllowanceCharge($args);
Expand All @@ -312,6 +325,53 @@ function update($args) {
$_lib['message']->add('Sted mangler p&aring; leverand&oslash;r kontoplan');
}
}
if(!$invoicein->IName) {
if($accountplan->AccountName) {
$args['invoicein_IName_' . $ID] = $accountplan->AccountName;
$_lib['message']->add('Navn kopiert fra leverand&oslash;r kontoplan');
} else {
$_lib['message']->add('Navn mangler p&aring; leverand&oslash;r kontoplan');
}
}
if(!$invoicein->IAddress) {
if($accountplan->Address) {
$args['invoicein_IAddress_' . $ID] = $accountplan->Address;
$_lib['message']->add('Adresse kopiert fra leverand&oslash;r kontoplan');
} else {
$_lib['message']->add('Addresse mangler p&aring; leverand&oslash;r kontoplan');
}
}
$changed_supplier_accountplan = $invoicein->SupplierAccountPlanID != $AccountPlanID;

// update all supplier related info on the invoice
if($changed_supplier_accountplan) {
$args['invoicein_IZipCode_' . $ID] = $accountplan->ZipCode;
if(!$accountplan->ZipCode) $_lib['message']->add('Postnummer mangler p&aring; leverand&oslash;r kontoplan');
$args['invoicein_ICity_' . $ID] = $accountplan->City;
if(!$accountplan->City) $_lib['message']->add('Sted mangler p&aring; leverand&oslash;r kontoplan');
$args['invoicein_IName_' . $ID] = $accountplan->AccountName;
if(!$accountplan->AccountName) $_lib['message']->add('Navn mangler p&aring; leverand&oslash;r kontoplan');
$args['invoicein_IAddress_' . $ID] = $accountplan->Address;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check out why this shows up on initial create for invoice

if(!$accountplan->Address) $_lib['message']->add('Addresse mangler p&aring; leverand&oslash;r kontoplan');
$args['invoicein_SupplierBankAccount_' . $ID] = $accountplan->DomesticBankAccount;
if(!$accountplan->DomesticBankAccount) $_lib['message']->add('Kontonummer mangler p&aring; leverand&oslash;r kontoplan');
$args['invoicein_DZipCode_' . $ID] = $accountplan->ZipCode;
$args['invoicein_DName_' . $ID] = $accountplan->AccountName;
$args['invoicein_DCity_' . $ID] = $accountplan->City;
$args['invoicein_DAddress_' . $ID] = $accountplan->Address;
}
if(!$invoicein->DZipCode) {
$args['invoicein_DZipCode_' . $ID] = $accountplan->ZipCode;
}
if(!$invoicein->DName) {
$args['invoicein_DName_' . $ID] = $accountplan->AccountName;
}
if(!$invoicein->DCity) {
$args['invoicein_DCity_' . $ID] = $accountplan->City;
}
if(!$invoicein->DAddress) {
$args['invoicein_DAddress_' . $ID] = $accountplan->Address;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the delivery address fields should go to the upper if block, since they should be updated on account plan change.

if(!$invoicein->SupplierBankAccount) {
if($accountplan->DomesticBankAccount) {
$args['invoicein_SupplierBankAccount_' . $ID] = $accountplan->DomesticBankAccount;
Expand All @@ -322,6 +382,31 @@ function update($args) {
$_lib['message']->add('Kontonummer mangler p&aring; leverand&oslash;r kontoplan');
}
}
if(!$invoicein->CustomerAccountPlanID) {
$args['invoicein_CustomerAccountPlanID_' . $ID] = $_lib['sess']->get_companydef('OrgNumber');
}
$args['invoicein_RemittanceAmount_'.$ID] = $args['invoicein_TotalCustPrice_'.$ID];

// update UnitCustPrice(unit price without tax) from UnitCostPrice(unit price with tax) if it is set
for($i = 1; $i <= $args['field_count']; $i++) {
$line_id = $args[$i];
if (!isset($args['invoiceinline_UnitCostPrice_'.$line_id])) continue;
$UnitCostPrice = (float)$_lib['convert']->Amount(array('value' => $args['invoiceinline_UnitCostPrice_'.$line_id], 'return' => 'value'));
$UnitCustPrice = (float)$_lib['convert']->Amount(array('value' => $args['invoiceinline_UnitCustPrice_'.$line_id], 'return' => 'value'));
$VATPercent = $_lib['convert']->Amount(array('value' => $args['invoiceinline_Vat_'.$line_id], 'return' => 'value'))/100.0;
if ($UnitCostPrice != 0) {
$args['invoiceinline_UnitCustPrice_'.$line_id] = $UnitCostPrice/($VATPercent+1);
// else update UnitCostPrice from UnitCustPrice
} elseif ($UnitCustPrice != 0) {
$args['invoiceinline_UnitCostPrice_'.$line_id] = $UnitCustPrice*($VATPercent+1);
}
}
// set the period as the period the invoice date belongs to
// and set due date if not set to X days after where X is credit days set for supplier
if ($args['invoicein_InvoiceDate_'.$ID] && !empty($args['invoicein_InvoiceDate_'.$ID])) {
$args['invoicein_Period_'.$ID] = strftime("%Y-%m", strtotime($args['invoicein_InvoiceDate_'.$ID]));
if ($args['invoicein_DueDate_'.$ID] == '0000-00-00' || $args['invoicein_DueDate_'.$ID] == '') $args['invoicein_DueDate_'.$ID] = strftime("%Y-%m-%d", strtotime($args['invoicein_InvoiceDate_'.$ID] . ' + ' . $accountplan->CreditDays . ' days'));
}

if(($args['invoicein_DepartmentID_'.$ID] === DB_NULL_PLACEHOLDER) && $accountplan->EnableDepartment == 1 && isset($accountplan->DepartmentID))
$args['invoicein_DepartmentID_'.$ID] = $accountplan->DepartmentID;
Expand All @@ -331,6 +416,11 @@ function update($args) {

#print_r($accountplan);
#print_r($args);
for ($i = 1; $i <= $args['field_count']; $i++) {
$invoiceinline_id = $args[$i];
$invoiceinline_accountplan = $accounting->get_accountplan_object($args['invoiceinline_AccountPlanID_'.$invoiceinline_id]);
if (!$invoiceinline_accountplan->EnableCar && !empty($args['invoiceinline_CarID_'.$invoiceinline_id])) $args['invoiceinline_CarID_'.$invoiceinline_id] = 0;
}

$tables_to_update = array(
'invoicein' => 'ID',
Expand All @@ -339,6 +429,45 @@ function update($args) {
$this->line_allowance_charge_table => 'InvoiceLineAllowanceChargeID');
$_lib['db']->db_update_multi_table($args, $tables_to_update);

// if manually created invoice(not imported from Fakturabank)
// calculate total cost for invoice
if (!$invoicein->Imported) {
$TotalCustPrice = self::recalculate_total_cust_price($ID);
$_lib['db']->db_update_multi_table(array('invoicein_TotalCustPrice_'.$ID => $TotalCustPrice), array('invoicein' => 'ID'));
}
}

// calculate total cost for invoice
function recalculate_total_cust_price($id) {
global $_lib;

$total = 0;

$query_invoicelines = "select * from invoiceinline where ID='$id' and Active <> 0 order by LineID asc";
$result_invoicelines = $_lib['db']->db_query($query_invoicelines);
while($invoicein_line = $_lib['db']->db_fetch_object($result_invoicelines)) {
$unit_cust_price = $invoicein_line->UnitCustPrice;
$quantity_delivered = $invoicein_line->QuantityDelivered;
$line_cust_price = $unit_cust_price * $quantity_delivered;

// include line's allowance/charge
$query_invoicelines_allowance_charge = "select * from invoicelineallowancecharge where InvoiceLineID='$invoicein_line->LineID' and InvoiceType = 'in'";
$result_invoicelines_allowance_charge = $_lib['db']->db_query($query_invoicelines_allowance_charge);
while($line_ac = $_lib['db']->db_fetch_object($result_invoicelines_allowance_charge)) {
$line_cust_price += (($line_ac->ChargeIndicator == 1) ? 1 : -1) * $line_ac->Amount;
}
$line_cost_price = $line_cust_price * (1 + ($invoicein_line->Vat / 100.0));
$total += $line_cost_price;
}

// include ivoice's allowance/charge
$query_invoice_allowance_charge = "select * from invoiceallowancecharge where InvoiceID='$id' and InvoiceType = 'in'";
$result_invoice_allowance_charge = $_lib['db']->db_query($query_invoice_allowance_charge);
while($ac = $_lib['db']->db_fetch_object($result_invoice_allowance_charge)) {
$ac_amount =(($ac->ChargeIndicator == 1) ? 1 : -1) * $ac->Amount * ( 1 + ($ac->VatPercent / 100.0));
$total += $ac_amount;
}
return $total;
}

function linenew($args) {
Expand Down Expand Up @@ -411,7 +540,19 @@ function linedelete($args) {
$_lib['db']->db_delete($query);
$invoicelineH['Active'] = 0;
$invoicelineH['LineID'] = $args['LineID'];
return $_lib['storage']->store_record(array('table' => 'invoiceinline', 'data' => $invoicelineH, 'debug' => false));

$ret = $_lib['storage']->store_record(array('table' => 'invoiceinline', 'data' => $invoicelineH, 'debug' => false));

$ID = $args['ID'];
$invoicein = $_lib['storage']->get_row(array('query' => "select * from invoicein where ID='$ID'"));
// if manually created invoice(not imported from Fakturabank)
// calculate total cost for invoice
if (!$invoicein->Imported) {
$TotalCustPrice = self::recalculate_total_cust_price($ID);
$_lib['db']->db_update_multi_table(array('invoicein_TotalCustPrice_'.$ID => $TotalCustPrice), array('invoicein' => 'ID'));
}

return $ret;
}

/***************************************************************************
Expand All @@ -420,19 +561,36 @@ function linedelete($args) {
* @return Current iteration
*/
public function add() {
global $_lib;
$dataH['CustomerBankAccount'] = $_lib['sess']->get_companydef('BankAccount');
$old_pattern = array("/[^0-9]/");
$new_pattern = array("");
$dataH['CustomerAccountPlanID'] = strtolower(preg_replace($old_pattern, $new_pattern , $_lib['sess']->get_companydef('OrgNumber')));
$add_invoicein = "INSERT INTO invoicein(ID, VoucherType, InvoiceDate, InsertedByPersonID, InsertedDateTime, Imported) VALUES(NULL, 'U', '" . $_lib['sess']->get_session('LoginFormDate') . "', " . $_lib['sess']->get_person('PersonID') . ", NOW(), 0)";
$_lib['db']->db_insert($add_invoicein);
return $_lib['db']->db_insert_id();
}

/***************************************************************************
* Delete incoming invoice
*/
public function delete() {
global $_lib;
$delete_invoiceinlines = "DELETE FROM invoiceinline WHERE ID = " . $this->ID . " AND ID IN (SELECT DISTINCT(ID) FROM invoicein WHERE JournalID IS NULL)";
$_lib['db']->db_delete($delete_invoiceinlines);
$delete_invoicein = "DELETE FROM invoicein WHERE ID = " . $this->ID . " AND JournalID IS NULL";
$_lib['db']->db_delete($delete_invoicein);
return true;
}
################################################################################################
#Journal the invoices automatically.
#Set the invoices as registered in fakturabank
#update the bankaccount in accountplan.
public function journal() {
global $_lib, $accounting;

$countjournaled = 0;

if(is_array($this->iteratorH)) {
$this->Journaled = 1; //#So that we immideately list the journaled vouchers

Expand Down Expand Up @@ -773,7 +931,7 @@ public function journal() {
}
else {
# Invoice is bookkept
print "Fakturaen er bilagsfrt<br>";
print "Fakturaen er bilagsf&oslash;rt<br>";
}
}

Expand Down
Loading