}
function add_item($type, $type_no, $date_, $due_date, $amount, $amount_allocated,
- $current_allocated, $ref, $early_discount=0, $early_days=0)
+ $current_allocated, $ref, $early_discount=0, $early_days=0, $discount=0)
{
if (floatcmp($amount, 0))
{
$this->allocs[count($this->allocs)] = new allocation_item($type, $type_no,
- $date_, $due_date, $amount, $amount_allocated, $current_allocated, $ref, $early_discount, $early_days);
- return true;
+ $date_, $due_date, $amount, $amount_allocated, $current_allocated, $ref, $early_discount, $early_days, $discount);
+ return $this->allocs[count($this->allocs)-1];
}
else
{
}
function update_item($index, $type, $type_no, $date_, $due_date,
- $amount, $amount_allocated, $current_allocated, $ref, $early_discount=0, $early_days=0)
+ $amount, $amount_allocated, $current_allocated, $ref, $early_discount=0, $early_days=0, $discount=0)
{
if (floatcmp($amount, 0))
{
$this->allocs[$index] = new allocation_item($type, $type_no,
- $date_, $due_date, $amount, $amount_allocated, $current_allocated, $ref, $early_discount, $early_days);
- return true;
+ $date_, $due_date, $amount, $amount_allocated, $current_allocated, $ref, $early_discount, $early_days, $discount);
+ return $this->allocs[$index];
}
else
{
}
function add_or_update_item($type, $type_no, $date_, $due_date,
- $amount, $amount_allocated, $current_allocated, $ref, $early_discount=0, $early_days=0)
+ $amount, $amount_allocated, $current_allocated, $ref, $early_discount=0, $early_days=0, $discount=0)
{
for ($i = 0; $i < count($this->allocs); $i++)
{
if (($item->type == $type) && ($item->type_no == $type_no))
{
return $this->update_item($i, $type, $type_no, $date_, $due_date,
- $amount, $amount_allocated, $current_allocated, $ref, $early_discount, $early_days);
+ $amount, $amount_allocated, $current_allocated, $ref, $early_discount, $early_days, $discount);
}
}
return $this->add_item($type, $type_no, $date_, $due_date,
- $amount, $amount_allocated, $current_allocated, $ref, $early_discount, $early_days);
+ $amount, $amount_allocated, $current_allocated, $ref, $early_discount, $early_days, $discount);
}
//
$this->amount = $trans["Total"];
}
}
- /* Now populate the array of possible (and previous actual) allocations
- for this customer/supplier. First get the transactions that have
- outstanding balances ie Total-alloc >0 */
+ /* Now populate the array of possible (and previous actual) allocations for this customer/supplier.
+ First get the transactions that have outstanding balances ie Total-alloc >0 */
$this->allocs = array();
if ($this->person_id)
{
if ($this->person_type==PT_SUPPLIER)
- $trans_items = get_allocatable_to_supp_transactions($this->person_id);
+ $trans_items = get_allocatable_to_supp_transactions($this->person_id, $this->trans_no, $this->type);
else
- $trans_items = get_allocatable_to_cust_transactions($this->person_id);
+ $trans_items = get_allocatable_to_cust_transactions($this->person_id, $this->trans_no, $this->type);
+
while ($myrow = db_fetch($trans_items))
{
- $this->add_item($myrow["type"], $myrow["trans_no"],
+ $this->add_or_update_item ($myrow["type"], $myrow["trans_no"],
sql2date($myrow["tran_date"]),
sql2date($myrow["due_date"]),
- $myrow["Total"], // trans total
- $myrow["alloc"], // trans total allocated
- 0, // this allocation
- $myrow["reference"], $myrow["early_discount"], $myrow["early_days"]);
+ $myrow["Total"], $myrow["alloc"]-$myrow["amt"], $myrow["amt"],
+ $myrow["reference"],
+ $myrow["early_discount"], $myrow["early_days"], $myrow["discount"]);
}
}
- if ($this->trans_no == 0) return; // this is new payment
-
- /* Now get trans that might have previously been allocated to by this trans
- NB existing entries where still some of the trans outstanding entered from
- above logic will be overwritten with the prev alloc detail below */
-
- if ($this->person_type==PT_SUPPLIER)
- $trans_items = get_allocatable_to_supp_transactions($this->person_id,
- $this->trans_no, $this->type);
- else
- $trans_items = get_allocatable_to_cust_transactions($this->person_id,
- $this->trans_no, $this->type);
-
- while ($myrow = db_fetch($trans_items))
- {
- $this->add_or_update_item ($myrow["type"], $myrow["trans_no"],
- sql2date($myrow["tran_date"]),
- sql2date($myrow["due_date"]),
- $myrow["Total"],
- $myrow["alloc"] - $myrow["amt"], $myrow["amt"], $myrow["reference"], $myrow["early_discount"], $myrow["early_days"]);
- }
}
//
// Update allocations in database.
if ($this->person_type == PT_SUPPLIER) {
add_supp_allocation($amount,
$this->type, $this->trans_no,
- $alloc_item->type, $alloc_item->type_no, $this->person_id, $this->date_);
+ $alloc_item->type, $alloc_item->type_no, $this->person_id, $this->date_, round2($alloc_item->early_discount*abs($alloc_item->amount), user_price_dec()));
update_supp_trans_allocation($alloc_item->type, $alloc_item->type_no, $this->person_id);
} else {
add_cust_allocation($amount,
$this->type, $this->trans_no,
- $alloc_item->type, $alloc_item->type_no, $this->person_id, $this->date_);
+ $alloc_item->type, $alloc_item->type_no, $this->person_id, $this->date_, round2($alloc_item->early_discount*abs($alloc_item->amount), user_price_dec()));
update_debtor_trans_allocation($alloc_item->type, $alloc_item->type_no, $this->person_id);
}
var $current_allocated;
var $early_discount; // nominal early payment discount according to payment terms
var $early_days; // days for early payment
+ var $discount_confirmed = false;
function __construct($type, $type_no, $date_, $due_date, $amount,
$amount_allocated, $current_allocated, $ref, $early_discount=0, $early_days=0)
$this->early_discount = $early_discount;
$this->early_days = $early_days;
}
+
+ function confirm_discount($confirmed)
+ {
+ $this->discount_confirmed = $confirmed;
+ }
}
//--------------------------------------------------------------------------------
$_POST['amount' . $id] = price_format($alloc_item->current_allocated);
$un_allocated = round((abs($alloc_item->amount) - $alloc_item->amount_allocated), 6);
- amount_cell($un_allocated, false,'', 'maxval'.$id);
- if ($early_discount) {
- $discount = price_format($alloc_item->early_discount*abs($alloc_item->amount));
- if ($reallocation)
- label_cell($discount, 'align=center');
- else
- check_cells(null, 'early_disc'.$id, $discount, false, false, 'align=center');
+ amount_cell($un_allocated-$alloc_item->current_allocated, false,'', 'left'.$id);
+
+ if ($early_discount) {
+ $discount = round2($alloc_item->early_discount*abs($alloc_item->amount),user_price_dec());
+ check_cells(null, 'early_disc'.$id, price_format($discount), false, false, 'align=center');
$total_discount += $discount;
} else {
- label_cell(_("N/A"), 'align=center'); hidden('early_disc'.$id, 0);
+ label_cell(_("N/A"), 'align=center', 'early_disc'.$id); hidden('early_disc'.$id, 0);
}
amount_cells(null, "amount" . $id);
- if (0) {
- label_cells('', '', '', 'colspan=2');
- } else {
- label_cell("<a href='#' name=Alloc$id onclick='allocate_all(this.name.substr(5));return true;'>"
- . _("All") . "</a>");
- label_cell("<a href='#' name=DeAll$id onclick='allocate_none(this.name.substr(5));return true;'>"
- . _("None") . "</a>".hidden("un_allocated" . $id,
- price_format($un_allocated), false));
- }
+
+ label_cell("<a href='#' name=Alloc$id onclick='allocate_all(this.name.substr(5));return true;'>"
+ . _("All") . "</a>");
+ label_cell("<a href='#' name=DeAll$id onclick='allocate_none(this.name.substr(5));return true;'>"
+ . _("None") . "</a>".hidden("un_allocated".$id, price_format($un_allocated), false));
end_row();
$total_allocated += input_num('amount' . $id);
{
global $SysPrefs;
- $total_allocated = 0;
+ $total_allocated = $discount=0;
for ($counter = 0; $counter < get_post("TotalNumberOfAllocs"); $counter++)
{
$_SESSION['alloc']->allocs[$counter]->current_allocated = input_num('amount' . $counter);
$total_allocated += input_num('amount' . $counter);
- }
+ $_SESSION['alloc']->allocs[$counter]->discount_confirmed = check_value('early_disc'.$counter) != 0;
+ $discount += check_value('early_disc'.$counter)
+ ? round2($_SESSION['alloc']->allocs[$counter]->early_discount*input_num('amount' . $counter), user_price_dec()) : 0;
+ }
$amount = abs($_SESSION['alloc']->amount);
- if ($total_allocated - ($amount + input_num('discount')) > $SysPrefs->allocation_settled_allowance())
+ if ($total_allocated - ($amount + $discount) > $SysPrefs->allocation_settled_allowance())
{
display_error(_("These allocations cannot be processed because the amount allocated is more than the total amount left to allocate."));
return false;
label_cell(sql2date($alloc_row['tran_date']));
$alloc_row['Total'] = round2($alloc_row['Total'], user_price_dec());
$alloc_row['amt'] = round2($alloc_row['amt'], user_price_dec());
- if ($alloc_row['type'] == ST_SUPPAYMENT || $alloc_row['type'] == ST_BANKPAYMENT || $alloc_row['type'] == ST_SUPPCREDIT)
- $alloc_row['Total'] = -$alloc_row['Total'];
- amount_cell($alloc_row['Total']);
- amount_cell($alloc_row['Total'] - $alloc_row['alloc']);
+ amount_cell(abs($alloc_row['Total']));
+ amount_cell(abs($alloc_row['Total']) - $alloc_row['alloc']);
amount_cell($alloc_row['amt']);
end_row();
switch ($person_type)
{
case PT_CUSTOMER :
- $alloc_result = get_allocatable_to_cust_transactions($person_id, $type_no, $type);
+ $alloc_result = get_allocatable_to_cust_transactions(0, $type_no, $type);
display_allocations($alloc_result, $total, _("Allocations"));
return;
case PT_SUPPLIER :
- $alloc_result = get_allocatable_to_supp_transactions($person_id, $type_no, $type);
+ $alloc_result = get_allocatable_to_supp_transactions(0, $type_no, $type);
display_allocations($alloc_result, $total, _("Allocations"));
return;
}
}
function blur_alloc(i) {
-
- var last = +i.getAttribute('_last')
- var left = get_amount('left_to_allocate', 1);
- var cur = Math.min(get_amount(i.name), get_amount('maxval'+i.name.substr(6), 1), last+left)
+ var id = i.name.substr(6)
+ var unallocated = get_amount('un_allocated'+id)
+ var cur = Math.max(Math.min(get_amount(i.name), unallocated, get_amount('left_to_allocate',1)+parseFloat(i.getAttribute('_last'))), 0)
price_format(i.name, cur, user.pdec);
- change = cur-last;
-
- var total = get_amount('total_allocated', 1)+change;
- left -= change;
-
- price_format('left_to_allocate', left, user.pdec, 1, 1);
- price_format('total_allocated', total, user.pdec, 1, 1);
+ price_format('left'+id, unallocated-cur, user.pdec, 1);
+ update_totals()
}
function update_totals() {
&& (get_amount('un_allocated'+docs[i]) == get_amount('amount'+docs[i])))
discount += get_amount('early_disc'+docs[i]);
}
- price_format('amount', amount-discount, user.pdec);
- price_format('discount', discount, user.pdec);
-
+ price_format('left_to_allocate', Math.abs(get_amount('total',1)-(amount-discount)), user.pdec, 1,1);
+ price_format('total_allocated', amount-discount, user.pdec, 1, 1);
+ price_format('total_discount', discount, user.pdec, 1, 1);
}
+
function allocate_all(doc) {
- var amount = get_amount('amount'+doc);
var unallocated = get_amount('un_allocated'+doc);
- var total = get_amount('total_allocated', 1);
- var left = get_amount('left_to_allocate', 1);
- total -= (amount-unallocated);
- left += (amount-unallocated);
- amount = unallocated;
- if(left<0) {
- total += left;
- amount += left;
- left = 0;
- }
- price_format('amount'+doc, amount, user.pdec);
- price_format('left_to_allocate', left, user.pdec, 1,1);
- price_format('total_allocated', total, user.pdec, 1, 1);
+ var cur = Math.min(unallocated, get_amount('left_to_allocate',1))
+ price_format('amount'+doc, cur, user.pdec);
+ price_format('left'+doc, 0, user.pdec, 1);
+ update_totals();
+
}
function allocate_none(doc) {
- amount = get_amount('amount'+doc);
- left = get_amount('left_to_allocate', 1);
- total = get_amount('total_allocated', 1);
- price_format('left_to_allocate',amount+left, user.pdec, 1, 1);
+ var unallocated = get_amount('un_allocated'+doc);
price_format('amount'+doc, 0, user.pdec);
- price_format('total_allocated', total-amount, user.pdec, 1, 1);
+ price_format('left'+doc, unallocated, user.pdec, 1);
+ update_totals();
}
var allocations = {
}
function blur_alloc(i) {
- var change = get_amount(i.name);
-
- if (i.name != 'amount' && i.name != 'charge' && i.name != 'discount')
- change = Math.min(change, get_amount('maxval'+i.name.substr(6), 1))
+ var id = i.name.substr(6)
+ var unallocated = get_amount('un_allocated'+id);
- price_format(i.name, change, user.pdec);
- if (i.name != 'amount' && i.name != 'charge') {
- if (change<0) change = 0;
- change = change-i.getAttribute('_last');
- if (i.name == 'discount') change = -change;
+ var cur = Math.max(Math.min(get_amount(i.name), unallocated), 0);
- var total = get_amount('amount')+change;
- price_format('amount', total, user.pdec, 0);
- }
+ price_format(i.name, cur, user.pdec);
+ price_format('left'+id, unallocated-cur, user.pdec, 1);
+ update_totals()
}
function update_totals() {
&& (get_amount('un_allocated'+docs[i]) == get_amount('amount'+docs[i])))
discount += get_amount('early_disc'+docs[i]);
}
+ console.info(discount);
price_format('amount', amount-discount, user.pdec);
- price_format('discount', discount, user.pdec);
+ price_format('discount', discount, user.pdec, 1);
}
function allocate_all(doc) {
- var unallocated = get_amount('maxval'+doc, 1);
+ var unallocated = get_amount('un_allocated'+doc);
price_format('amount'+doc, unallocated, user.pdec);
+ price_format('left'+doc, 0, user.pdec, 1);
update_totals();
}
function allocate_none(doc) {
+ var unallocated = get_amount('un_allocated'+doc);
price_format('amount'+doc, 0, user.pdec);
+ price_format('left'+doc, unallocated, user.pdec, 1);
update_totals();
}
display_heading2(_("Date:") . " <b>" . $cart->date_ . "</b>");
- display_heading2(_("Total:"). " <b>" . price_format(-$cart->bank_amount).' '.$cart->currency."</b>");
-
if (floatcmp($cart->bank_amount, $cart->amount))
- {
- $total = _("Amount ot be settled:") . " <b>" . price_format(-$cart->amount).' '.$cart->person_curr."</b>";
- if ($cart->currency != $cart->person_curr)
- $total .= sprintf(" (%s %s/%s)", exrate_format($cart->bank_amount/$cart->amount), $cart->currency, $cart->person_curr);
- display_heading2($total);
- }
+ display_heading2(_("Total:"). " <b>" . price_format(-$cart->bank_amount).' '.$cart->currency."</b>");
+
+ $total = _("Amount ot be settled:") . " <b>" . '<span id="total">'.price_format(-$cart->amount).'</span> '.$cart->person_curr."</b>";
+ if ($cart->currency != $cart->person_curr)
+ $total .= sprintf(" (%s %s/%s)", exrate_format($cart->bank_amount/$cart->amount), $cart->currency, $cart->person_curr);
+ display_heading2($total);
echo "<br>";
div_start('alloc_tbl');
}
+$all_settled = !db_num_rows(get_allocatable_to_supp_transactions(get_post('supplier_id')));
+if ($all_settled)
+ display_note('<b>'.
+ ($supplier_id ? _("There is no unsettled transactions for this supplier.")
+ :_("There is no unsettled transactions.")).'</b><p>');
+
$sql = get_allocatable_from_supp_sql($supplier_id, $settled);
$cols = array(
//----------------------------------------------------------------------------------------
function add_supp_allocation($amount, $trans_type_from, $trans_no_from,
- $trans_type_to, $trans_no_to, $person_id, $date_)
+ $trans_type_to, $trans_no_to, $person_id, $date_, $discount=0)
{
$date = date2sql($date_);
$sql = "INSERT INTO ".TB_PREF."supp_allocations (
- amt, date_alloc,
+ amt, discount, date_alloc,
trans_type_from, trans_no_from, trans_no_to, trans_type_to, person_id)
- VALUES (".db_escape($amount).", '$date', "
+ VALUES (".db_escape($amount).",".db_escape($discount).", '$date', "
.db_escape($trans_type_from).", ".db_escape($trans_no_from).", "
.db_escape($trans_no_to).", ".db_escape($trans_type_to).", ".db_escape($person_id).")";
function delete_supp_allocation($trans_id)
{
$sql = "DELETE FROM ".TB_PREF."supp_allocations WHERE id = ".db_escape($trans_id);
- db_query($sql, "The existing allocation $trans_id could not be deleted");
+ return db_query($sql, "The existing allocation $trans_id could not be deleted");
}
//----------------------------------------------------------------------------------------
return $sql;
}
-function get_allocatable_purch_orders($supplier_id = null, $trans_no=null, $type=null)
+function get_allocatable_purch_orders($supplier_id, $trans_no=null, $type=null)
{
$due_dates = "SELECT order_no, MIN(delivery_date) as date
FROM ".TB_PREF."purch_order_details det
porder.alloc,
due_dates.date as due_date,
supplier.address,
- amt,
+ ".(isset($trans_no) ? "IF(alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type) . ", alloc.amt, 0) amt" : "alloc.amt").",
+ ".(isset($trans_no) ? "IF(alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type) . ", alloc.discount, 0) discount" : "alloc.discount").",
supp_reference as supp_ref,
0, 0
FROM ".TB_PREF."purch_orders as porder
LEFT JOIN ($due_dates) due_dates ON due_dates.order_no=porder.order_no
WHERE total>0";
- if ($trans_no != null and $type != null)
- {
- $sql .= " AND alloc.trans_no_from=".db_escape($trans_no)."
- AND alloc.trans_type_from=".db_escape($type);
- }
- else
- {
- $sql .= " AND ISNULL(grn.purch_order_no)"; // only sales orders no yet received
- }
+ $sql .= " AND ( ISNULL(grn.purch_order_no)" // only orders no yet received
+ ."OR (alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type)."))";
+
if ($supplier_id)
$sql .= " AND porder.supplier_id=".db_escape($supplier_id);
+ elseif (isset($trans_no) && isset($type))
+ $sql .= " AND alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type);
$sql .= " GROUP BY porder.order_no, grn.purch_order_no";
return $sql;
}
+
//-------------------------------------------------------------------------------------------------------------
+//
+// Returns all allocatable purchase transactions including all settled with selected payment.
+//
+// 1. not fully settled; supplier_id!=0, trans_no/type!=null (for trans edition)
+// 2. for given transaction; supplier_id=null, trans_no/type!=null (for transaction view)
+// 3. for supplier, not fully settled supplier_id!=0, trans_no/type=null (non fully settled documents for supplier exists)
+// 4. for all suppliers, not fully settled supplier_id==0, trans_no/type=null (any non fully settled documents exists)
-function get_allocatable_to_supp_transactions($supplier_id=null, $trans_no=null, $type=null)
+function get_allocatable_to_supp_transactions($supplier_id, $trans_no=null, $type=null)
{
$sql = "SELECT
trans.type,
trans.alloc,
trans.due_date,
trans.supplier_id,
- amt,
+ IF(alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type) . ", alloc.amt, 0) amt,
+ IF(alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type) . ", alloc.discount, 0) discount,
supp_reference,
pmt.early_days,
pmt.early_discount
LEFT JOIN ".TB_PREF."supp_allocations as alloc
ON trans.trans_no = alloc.trans_no_to AND trans.type = alloc.trans_type_to AND alloc.person_id=trans.supplier_id";
- if ($trans_no != null and $type != null)
- {
- $sql .= " WHERE alloc.trans_no_from=".db_escape($trans_no)."
- AND alloc.trans_type_from=".db_escape($type);
- }
- else
- {
- $sql .= " WHERE round(ov_amount+ov_gst+ov_discount-alloc,6) > 0
- AND trans.type NOT IN (".implode(',',array(ST_SUPPAYMENT, ST_BANKPAYMENT)).")";
- }
+ $sql .= " WHERE (
+ (round(ov_amount+ov_gst+ov_discount-alloc,6) > 0
+ AND trans.type NOT IN (".implode(',',array(ST_SUPPAYMENT, ST_BANKPAYMENT))."))
+ OR (alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type)."))";
if ($supplier_id)
- $sql .= " AND supplier.supplier_id=".db_escape($supplier_id);
+ $sql .= " AND trans.supplier_id=".db_escape($supplier_id);
+ elseif (isset($trans_no) && isset($type))
+ $sql .= " AND alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type);
+ $sql .= " GROUP BY type, trans_no"; // avoids row multiplication for journal entry containing multiply suppliers
$orders = get_allocatable_purch_orders($supplier_id, $trans_no, $type);
- $sql = "($sql ORDER BY trans_no) \nUNION \n($orders)";
+ $sql = "($sql) \nUNION \n($orders) ORDER BY amt, due_date";
- return db_query($sql." ORDER BY due_date", "Cannot retreive alloc to transactions");
+ return db_query($sql, "Cannot retreive alloc to transactions");
}
//-------------------------------------------------------------------------------------------------------------
return $result;
}
+function save_supp_payment($cart, $supplier_id, $bank_account, $trans_date, $ref, $amount, $memo, $charge, $bank_amount)
+{
+ begin_transaction(__FUNCTION__, func_get_args());
+
+ $discount = 0;
+ foreach($cart->allocs as $alloc)
+ if ($alloc->discount_confirmed)
+ $discount += $alloc->early_discount*$alloc->amount;
+
+ $payment_no = write_supp_payment($cart->trans_no, $supplier_id, $bank_account, $trans_date, $ref, $amount,
+ $discount, $memo, $charge, $bank_amount);
+
+ $cart->trans_no = $payment_no;
+ $cart->date_ = $trans_date;
+ $cart->write();
+
+ commit_transaction();
+
+ return $payment_no;
+}
+
}
}
- if (@$_POST['discount'] == "")
- {
- $_POST['discount'] = 0;
- }
-
- if (!check_num('discount', 0))
- {
- display_error(_("The entered discount is invalid or less than zero."));
- set_focus('amount');
- return false;
- }
-
- //if (input_num('amount') - input_num('discount') <= 0)
if (input_num('amount') <= 0)
{
display_error(_("The total of the amount and the discount is zero or negative. Please enter positive values."));
function handle_add_payment()
{
- $payment_id = write_supp_payment(0, $_POST['supplier_id'], $_POST['bank_account'],
- $_POST['DatePaid'], $_POST['ref'], input_num('amount'), input_num('discount'), $_POST['memo_'],
+ $payment_id = save_supp_payment($_SESSION['alloc'], $_POST['supplier_id'], $_POST['bank_account'],
+ $_POST['DatePaid'], $_POST['ref'], input_num('amount'), $_POST['memo_'],
input_num('charge'), input_num('bank_amount', input_num('amount')));
new_doc_date($_POST['DatePaid']);
- $_SESSION['alloc']->trans_no = $payment_id;
- $_SESSION['alloc']->date_ = $_POST['DatePaid'];
- $_SESSION['alloc']->write();
-
unset($_POST['bank_account']);
unset($_POST['DatePaid']);
unset($_POST['currency']);
div_end();
start_table(TABLESTYLE, "width='60%'");
- amount_row(_("Amount of Discount:"), 'discount', null, '', $supplier_currency);
+ label_row(_("Total Discount:"), price_format(input_num('discount')), '', '', 0, 'discount');
amount_row(_("Amount of Payment:"), 'amount', null, '', $supplier_currency);
textarea_row(_("Memo:"), 'memo_', null, 22, 4);
end_table(1);
+ hidden('discount', null);
+
submit_center('ProcessSuppPayment',_("Enter Payment"), true, '', 'default');
end_form();
$rep->SetCommonData($myrow, null, $myrow, $baccount, ST_CUSTPAYMENT, $contacts);
$rep->SetHeaderType('Header2');
$rep->NewPage();
- $result = get_allocatable_to_cust_transactions($myrow['debtor_no'], $myrow['trans_no'], $myrow['type']);
+ $result = get_allocatable_to_cust_transactions(0, $myrow['trans_no'], $myrow['type']);
$doctype = ST_CUSTPAYMENT;
$rep->SetCommonData($myrow, null, $myrow, $baccount, ST_SUPPAYMENT, $contacts);
$rep->SetHeaderType('Header2');
$rep->NewPage();
- $result = get_allocatable_to_supp_transactions($myrow['supplier_id'], $myrow['trans_no'], $myrow['type']);
+ $result = get_allocatable_to_supp_transactions(0, $myrow['trans_no'], $myrow['type']);
$doctype = ST_SUPPAYMENT;
display_heading($cart->person_name);
display_heading2(_("Date:") . " <b>" . $cart->date_ . "</b>");
- display_heading2(_("Total:"). " <b>" . price_format($cart->bank_amount).' '.$cart->currency."</b>");
if (floatcmp($cart->bank_amount, $cart->amount))
- {
- $total = _("Amount ot be settled:") . " <b>" . price_format($cart->amount).' '.$cart->person_curr."</b>";
- if ($cart->currency != $cart->person_curr)
- $total .= sprintf(" (%s %s/%s)", exrate_format($cart->bank_amount/$cart->amount), $cart->currency, $cart->person_curr);
- display_heading2($total);
- }
+ display_heading2(_("Total:"). " <b>" . price_format($cart->bank_amount).' '.$cart->currency."</b>");
+
+ $total = _("Amount to be settled:") . " <b>" . '<span id="total">'.price_format($cart->amount).'</span> '.$cart->person_curr."</b>";
+ if ($cart->currency != $cart->person_curr)
+ $total .= sprintf(" (%s %s/%s)", exrate_format($cart->bank_amount/$cart->amount), $cart->currency, $cart->person_curr);
+ display_heading2($total);
echo "<br>";
{
global $all_settled;
- return ($row['settled']&&!get_post('ShowSettled')) || (!$row['settled'] && $all_settled) ? '' : pager_link(_("Allocate"),
+ return pager_link(_("Allocate"),
"/sales/allocations/customer_allocate.php?trans_no="
.$row["trans_no"] . "&trans_type=" . $row["type"]. "&debtor_no=" . $row["debtor_no"], ICON_ALLOC);
}
}
$all_settled = !db_num_rows(get_allocatable_to_cust_transactions($customer_id));
+
if ($all_settled)
- display_note('<b>'._("There is no unsettled transactions for this customer.").'</b>');
+ display_note('<b>'.
+ ($customer_id ? _("There is no unsettled transactions for this customer.")
+ :_("There is no unsettled transactions.")).'</b><p>');
$sql = get_allocatable_from_cust_sql($customer_id, $settled);
}
}
- if (@$_POST['discount'] == "")
- {
- $_POST['discount'] = 0;
- }
-
- if (!check_num('discount')) {
- display_error(_("The entered discount is not a valid number."));
- set_focus('discount');
- return false;
- }
-
if (input_num('amount') <= 0) {
display_error(_("The balance of the amount and discount is zero or negative. Please enter valid amounts."));
- set_focus('discount');
+ set_focus('amount');
return false;
}
$new_pmt = !$_SESSION['alloc']->trans_no;
$payment_no = save_cust_payment($_SESSION['alloc'], get_post('customer_id'), get_post('BranchID'), get_post('bank_account'),
- get_post('DateBanked'), get_post('ref'), input_num('amount'), input_num('discount'), get_post('memo_'),
+ get_post('DateBanked'), get_post('ref'), input_num('amount'), get_post('memo_'),
input_num('charge'), input_num('bank_amount', input_num('amount')));
unset($_SESSION['alloc']);
}
}
+
//----------------------------------------------------------------------------------------------
$new = !$_SESSION['alloc']->trans_no;
start_form();
start_table(TABLESTYLE, "width='60%'");
-amount_row(_("Amount of Discount:"), 'discount', null, '', $cust_currency);
+label_row(_("Total Discount:"), price_format(input_num('discount')), '','', 0, 'discount');
amount_row(_("Amount:"), 'amount', null, '', $cust_currency);
textarea_row(_("Memo:"), 'memo_', null, 22, 4);
end_table(1);
+hidden('discount', null);
+
if ($new)
submit_center('AddPaymentItem', _("Add Payment"), true, '', 'default');
else
//----------------------------------------------------------------------------------------
function add_cust_allocation($amount, $trans_type_from, $trans_no_from,
- $trans_type_to, $trans_no_to, $person_id, $date_)
+ $trans_type_to, $trans_no_to, $person_id, $date_, $discount=0)
{
$date = date2sql($date_);
$sql = "INSERT INTO ".TB_PREF."cust_allocations (
- amt, date_alloc,
+ amt, discount, date_alloc,
trans_type_from, trans_no_from, trans_no_to, trans_type_to, person_id)
- VALUES ($amount, '$date', ".db_escape($trans_type_from).", ".db_escape($trans_no_from).", ".db_escape($trans_no_to)
+ VALUES (".db_escape($amount).",".db_escape($discount).", '$date', "
+ .db_escape($trans_type_from).", ".db_escape($trans_no_from).", ".db_escape($trans_no_to)
.", ".db_escape($trans_type_to).", ".db_escape($person_id).")";
db_query($sql, "A customer allocation could not be added to the database");
trans.version,
round(abs(ov_amount+ov_gst+ov_freight+ov_freight_tax+ov_discount-alloc),6) <= 0 AS settled,
trans.debtor_no
-
FROM "
- .TB_PREF."debtor_trans as trans, "
+ .TB_PREF."debtor_trans as trans
+ LEFT JOIN ".TB_PREF."cust_allocations as alloc
+ ON trans.trans_no = alloc.trans_no_to AND trans.type = alloc.trans_type_to AND alloc.person_id=trans.debtor_no,"
.TB_PREF."debtors_master as debtor"
." WHERE trans.debtor_no=debtor.debtor_no
AND (((type=".ST_CUSTPAYMENT." OR type=".ST_BANKDEPOSIT.") AND (trans.ov_amount+ov_discount > 0))
if ($customer_id != null)
$sql .= " AND trans.debtor_no = ".db_escape($customer_id);
-
+ $sql .= " GROUP BY trans_no, type";
return $sql;
}
-function get_allocatable_sales_orders($customer_id = null, $trans_no=null, $type=null)
+function get_allocatable_sales_orders($customer_id, $trans_no=null, $type=null)
{
$sql = "SELECT
sorder.trans_type as type,
sorder.delivery_date as due_date,
debtor.address,
sorder.version,
- amt,
+ ".(isset($trans_no) ? "IF(alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type) . ", alloc.amt, 0) amt" : "alloc.amt").",
+ ".(isset($trans_no) ? "IF(alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type) . ", alloc.discount, 0) discount" : "alloc.discount").",
sorder.debtor_no,
sorder.branch_code,
pmt.early_days,
WHERE prep_amount>0 AND dt.type=".ST_SALESINVOICE." GROUP BY order_) as invoiced ON sorder.order_no = invoiced.order_
WHERE sorder.trans_type=".ST_SALESORDER;
- if ($trans_no != null and $type != null)
- {
- $sql .= " AND alloc.trans_no_from=".db_escape($trans_no)."
- AND alloc.trans_type_from=".db_escape($type);
- }
- else
- {
- $sql .= " AND round(sorder.prep_amount)>0 and Total>0"; // only sales orders with prepayment level set and no yet fully invoiced
- }
+ $sql .= " AND ((round(sorder.prep_amount)>0 and Total>0)" // only sales orders with prepayment level set and no yet fully invoiced
+ ." OR (alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type)."))";
+
if ($customer_id)
$sql .= " AND sorder.debtor_no=".db_escape($customer_id);
+ elseif (isset($trans_no) && isset($type))
+ $sql .= " AND alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type);
$sql .= " GROUP BY sorder.order_no";
return $sql;
}
+
//-------------------------------------------------------------------------------------------------------------
+//
+// Returns all allocatable sales transactions including all settled with selected payment.
+//
+// 1. not fully settled; customer_id!=0, trans_no/type!=null (for trans edition)
+// 2. for given transaction; customer_id=null, trans_no/type!=null (for transaction view)
+// 3. for customer, not fully settled customer_id!=0, trans_no/type=null (non fully settled documents for customer exists)
+// 4. for all customers, not fully settled customer_id==0, trans_no/type=null (any non fully settled documents exists)
-function get_allocatable_to_cust_transactions($customer_id = null, $trans_no=null, $type=null)
+function get_allocatable_to_cust_transactions($customer_id, $trans_no=null, $type=null)
{
$sql = "SELECT
trans.type,
trans.tran_date,
debtor.name AS DebtorName,
debtor.curr_code,
- IF(prep_amount, prep_amount, ov_amount+ov_gst+ov_freight+ov_freight_tax+ov_discount) AS Total,
- trans.alloc,
+ trans.debtor_no,
+ trans.branch_code,
trans.due_date,
debtor.address,
trans.version,
- amt,
- trans.debtor_no,
- trans.branch_code,
+ IF(prep_amount, prep_amount, ov_amount+ov_gst+ov_freight+ov_freight_tax+ov_discount) AS Total,
+ trans.alloc,
+ ".(isset($trans_no) ? "IF(alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type) . ", alloc.amt, 0) amt" : "alloc.amt").",
+ ".(isset($trans_no) ? "IF(alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type) . ", alloc.discount, 0) discount" : "alloc.discount").",
pmt.early_days,
pmt.early_discount
- FROM ".TB_PREF."debtor_trans as trans
- LEFT JOIN ".TB_PREF."cust_allocations as alloc
- ON trans.trans_no = alloc.trans_no_to AND trans.type = alloc.trans_type_to AND alloc.person_id=trans.debtor_no
- LEFT JOIN ".TB_PREF."payment_terms as pmt ON trans.payment_terms=pmt.id,"
- .TB_PREF."debtors_master as debtor
- WHERE
- trans.debtor_no=debtor.debtor_no";
+ FROM ".TB_PREF."debtor_trans as trans
+ LEFT JOIN ".TB_PREF."cust_allocations as alloc
+ ON trans.trans_no = alloc.trans_no_to AND trans.type = alloc.trans_type_to AND alloc.person_id=trans.debtor_no
+ LEFT JOIN ".TB_PREF."payment_terms as pmt ON trans.payment_terms=pmt.id
+ LEFT JOIN ".TB_PREF."debtors_master as debtor ON trans.debtor_no=debtor.debtor_no";
+
+ $sql .= " WHERE (round(IF(trans.type IN(".ST_CUSTCREDIT.",".ST_BANKDEPOSIT.",".ST_CUSTPAYMENT."),-1,IF(trans.type=".ST_CUSTDELIVERY.",0,1))"
+ ."*IF(prep_amount, prep_amount, ov_amount+ov_gst+ov_freight+ov_freight_tax+ov_discount)-IFNULL(alloc,0),6) > 0
+ OR (alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type) . "))";
+
if ($customer_id)
$sql .= " AND trans.debtor_no=".db_escape($customer_id);
+ elseif (isset($trans_no) && isset($type))
+ $sql .= " AND alloc.trans_no_from=".db_escape($trans_no)." AND alloc.trans_type_from=".db_escape($type);
- if ($trans_no != null and $type != null)
- {
- $sql .= " AND alloc.trans_no_from=".db_escape($trans_no)."
- AND alloc.trans_type_from=".db_escape($type);
- }
- else
- {
- $sql .= "
- AND (
- trans.type='".ST_SALESINVOICE."'
- AND round(IF(prep_amount, prep_amount, ov_amount+ov_gst+ov_freight+ov_freight_tax+ov_discount)-alloc,6) > 0
- OR
- trans.type='". ST_CUSTCREDIT."'
- AND round(-IF(prep_amount, prep_amount, ov_amount+ov_gst+ov_freight+ov_freight_tax+ov_discount)-alloc,6) > 0
- OR
- trans.type = '". ST_JOURNAL."'
- AND ov_amount+ov_gst+ov_freight+ov_freight_tax+ov_discount>0
- AND ov_amount+ov_gst+ov_freight+ov_freight_tax+ov_discount>alloc
- OR
- trans.type = '". ST_BANKPAYMENT."'
- AND ov_amount+ov_gst+ov_freight+ov_freight_tax+ov_discount>0
- AND ov_amount+ov_gst+ov_freight+ov_freight_tax+ov_discount>alloc
- )";
- $sql .= " GROUP BY type, trans_no";
- }
+ $sql .= " GROUP BY type, trans_no"; // avoids row multiplication for journal entry containing multiply customers
$orders = get_allocatable_sales_orders($customer_id, $trans_no, $type);
- $sql = "($sql ORDER BY trans_no) \nUNION \n($orders)";
+ $sql = "($sql) \nUNION \n($orders) ORDER BY amt, due_date";
return db_query($sql, "Cannot retreive alloc to transactions");
}
trans.due_date,
debtor.address,
trans.version,
- amt,
+ alloc.amt,
+ alloc.discount,
trans.debtor_no
FROM ".TB_PREF."debtor_trans as trans,"
.TB_PREF."debtors_master as debtor,"
}
function save_cust_payment($cart, $customer_id, $branch_id,
- $bank_account, $trans_date, $ref, $amount, $discount, $memo, $charge, $bank_amount)
+ $bank_account, $trans_date, $ref, $amount, $memo, $charge, $bank_amount)
{
begin_transaction(__FUNCTION__, func_get_args());
+ $discount = 0;
+ foreach($cart->allocs as $alloc)
+ if ($alloc->discount_confirmed)
+ $discount += $alloc->early_discount*$alloc->amount;
+
$payment_no = write_customer_payment($cart->trans_no, $customer_id, $branch_id,
$bank_account, $trans_date, $ref, $amount, $discount, $memo, 0, $charge, $bank_amount);
ALTER TABLE `0_payment_terms` DROP COLUMN `day_in_following_month`;
ALTER TABLE `0_payment_terms` ADD COLUMN `early_discount` double NOT NULL DEFAULT '0' AFTER `days`;
ALTER TABLE `0_payment_terms` ADD COLUMN `early_days` int(11) NOT NULL DEFAULT '0' AFTER `early_discount`;
+
+ALTER TABLE `0_cust_allocations` ADD COLUMN `discount` double unsigned DEFAULT '0' AFTER `amt`;
+ALTER TABLE `0_supp_allocations` ADD COLUMN `discount` double unsigned DEFAULT '0' AFTER `amt`;
+
+# please define and set payment terms with discount manually per customer when needed
+ALTER TABLE `0_debtors_master` DROP COLUMN `pymt_discount`;
+
+# this update works only for single pay for invoice discounts, so may need additional manual fixes in more complex cases
+UPDATE `0_cust_allocations` ca
+ LEFT JOIN `0_debtor_trans` pay ON pay.`type`=ca.`trans_type_from` AND pay.`trans_no`=ca.`trans_no_from`
+ LEFT JOIN `0_debtor_trans` trans ON trans.`type`=ca.`trans_type_to` AND trans.`trans_no`=ca.`trans_no_to`
+SET ca.discount=pay.ov_discount
+ WHERE pay.ov_discount != 0 AND pay.ov_amount+pay.ov_discount = trans.ov_amount+trans.ov_gst+trans.ov_freight+trans.ov_freight_tax;
+
+UPDATE `0_supp_allocations` sa
+ LEFT JOIN `0_supp_trans` pay ON pay.`type`=sa.`trans_type_from` AND pay.`trans_no`=sa.`trans_no_from`
+ LEFT JOIN `0_supp_trans` trans ON trans.`type`=sa.`trans_type_to` AND trans.`trans_no`=sa.`trans_no_to`
+SET sa.discount=pay.ov_discount
+ WHERE pay.ov_discount != 0 AND pay.ov_amount+pay.ov_discount = trans.ov_amount+trans.ov_gst;
`id` int(11) NOT NULL AUTO_INCREMENT,
`person_id` int(11) DEFAULT NULL,
`amt` double unsigned DEFAULT NULL,
+ `discount` double unsigned DEFAULT '0',
`date_alloc` date NOT NULL DEFAULT '0000-00-00',
`trans_no_from` int(11) DEFAULT NULL,
`trans_type_from` int(11) DEFAULT NULL,
-- Data of table `0_cust_allocations` --
INSERT INTO `0_cust_allocations` VALUES
-('1', '1', '6240', '2018-05-10', '1', '12', '1', '10'),
-('2', '1', '300', '2018-05-07', '2', '12', '2', '10'),
-('3', '1', '0', '2018-05-07', '3', '12', '4', '10'),
-('4', '1', '1250', '2019-01-21', '4', '12', '5', '10');
+('1', '1', '6240', '0', '2018-05-10', '1', '12', '1', '10'),
+('2', '1', '300', '0', '2018-05-07', '2', '12', '2', '10'),
+('3', '1', '0', '0', '2018-05-07', '3', '12', '4', '10'),
+('4', '1', '1250', '0', '2019-01-21', '4', '12', '5', '10');
-- Structure of table `0_cust_branch` --
`id` int(11) NOT NULL AUTO_INCREMENT,
`person_id` int(11) DEFAULT NULL,
`amt` double unsigned DEFAULT NULL,
+ `discount` double unsigned DEFAULT '0',
`date_alloc` date NOT NULL DEFAULT '0000-00-00',
`trans_no_from` int(11) DEFAULT NULL,
`trans_type_from` int(11) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`person_id` int(11) DEFAULT NULL,
`amt` double unsigned DEFAULT NULL,
+ `discount` double unsigned DEFAULT '0',
`date_alloc` date NOT NULL DEFAULT '0000-00-00',
`trans_no_from` int(11) DEFAULT NULL,
`trans_type_from` int(11) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`person_id` int(11) DEFAULT NULL,
`amt` double unsigned DEFAULT NULL,
+ `discount` double unsigned DEFAULT '0',
`date_alloc` date NOT NULL DEFAULT '0000-00-00',
`trans_no_from` int(11) DEFAULT NULL,
`trans_type_from` int(11) DEFAULT NULL,