function send_emails($selected_option, $email_receive = false, $hash = "", $is_a_reply_comment = false, $files = array()) { $current_user =& singleton("current_user"); $e = $this->get_parent_object(); $type = $e->classname . "_comments"; $body = $this->get_value("comment"); if (is_object($email_receive)) { list($from_address, $from_name) = parse_email_address($email_receive->mail_headers["from"]); } if ($is_a_reply_comment) { $id = $this->get_value("commentLinkID"); } else { $id = $this->get_id(); } $recipients = comment::get_email_recipients($selected_option, "comment", $id); list($to_address, $bcc, $successful_recipients) = comment::get_email_recipient_headers($recipients, $from_address); if ($to_address || $bcc || $successful_recipients) { $email = new email_send(); if ($email_receive) { list($email_receive_header, $email_receive_body) = $email_receive->get_raw_header_and_body(); $email->set_headers($email_receive_header); $email->set_body($email_receive_body, $email_receive->mail_text); // Remove any existing To/Cc header, to prevent the email getting sent to the same recipients again. $email->del_header("To"); $email->del_header("Cc"); $subject = $email->get_header("subject"); $subject = trim(preg_replace("/{Key:[^}]*}.*\$/i", "", $subject)); } else { $email->set_body($body); if ($files) { // (if we're bouncing a complete email body the attachments are already included, else do this...) foreach ((array) $files as $file) { $email->add_attachment($file["fullpath"]); } } else { $email->set_content_type(); } } $bcc && $email->add_header("Bcc", $bcc); // nuke bounce headers - mail won't send properly otherwise $email->del_header("Resent-From"); $email->del_header("Resent-Date"); $email->del_header("Resent-Message-ID"); $email->del_header("Resent-To"); $email->add_header("X-Alloc-CommentID", $this->get_id()); if (is_object($e) && method_exists($e, "get_name")) { $email->add_header("X-Alloc-" . ucwords($e->classname), $e->get_name()); $email->add_header("X-Alloc-" . ucwords($e->key_field->get_name()), $e->get_id()); } // Add project header too, if possible if (has("project") && $e->classname != "project" && isset($e->data_fields["projectID"])) { $p = $e->get_foreign_object("project"); $email->add_header("X-Alloc-Project", $p->get_value("projectName")); $email->add_header("X-Alloc-ProjectID", $p->get_id()); } $email->set_to_address($to_address); $messageid = $email->set_message_id($hash); $subject_extra = "{Key:" . $hash . "}"; $email->set_date(); if (!$subject) { $tpl = config::get_config_item("emailSubject_" . $e->classname . "Comment"); $tpl and $subject = commentTemplate::populate_string($tpl, $e->classname, $e->get_id()); $e->classname != "task" and $prefix = ucwords($e->classname) . " Comment: "; $subject or $subject = $prefix . $e->get_id() . " " . $e->get_name(DST_VARIABLE); } $email->set_subject($subject . " " . $subject_extra); $email->set_message_type($type); // If from name is empty, then use the email address instead // eg: From: jon@jonny.com -> From: "jon@jonny.com via allocPSA" <*****@*****.**> $from_name or $from_name = $from_address; is_object($current_user) && !$from_name and $from_name = $current_user->get_name(); if (defined("ALLOC_DEFAULT_FROM_ADDRESS") && ALLOC_DEFAULT_FROM_ADDRESS) { if (config::for_cyber()) { $email->set_reply_to('"All parties via allocPSA" ' . ALLOC_DEFAULT_FROM_ADDRESS); $email->set_from('"' . str_replace('"', '', $from_name) . ' via allocPSA" ' . ALLOC_DEFAULT_FROM_ADDRESS); } else { $email->set_reply_to('"All parties" ' . ALLOC_DEFAULT_FROM_ADDRESS); $email->set_from('"' . str_replace('"', '', $from_name) . '" ' . ALLOC_DEFAULT_FROM_ADDRESS); } } else { if (is_object($current_user) && $current_user->get_from()) { $f = $current_user->get_from(); } else { $f = config::get_config_item("allocEmailAdmin"); } $email->set_reply_to($f); $email->set_from($f); } if ($email->send(false)) { return array($successful_recipients, $messageid); } } }
<?php // Cyber-only patch, revoking inbox privileges if (config::for_cyber()) { $db = new db_alloc(); $db->query("UPDATE permission SET actions = 1 WHERE tableName = 'inbox' AND roleName = 'manage'"); $db->query("UPDATE permission SET actions = 1 WHERE tableName = 'inbox' AND roleName = 'admin'"); }
function createTransactions($status = "pending") { // So this will only create transaction if: // - The timesheet status is admin // - There is a recipient_tfID - that is the money is going to a TF $db = new db_alloc(); $project = $this->get_foreign_object("project"); $projectName = $project->get_value("projectName"); $personName = person::get_fullname($this->get_value("personID")); $company_tfID = config::get_config_item("mainTfID"); $cost_centre = $project->get_value("cost_centre_tfID") or $cost_centre = $company_tfID; $this->fromTfID = $cost_centre; $this->load_pay_info(); if ($this->get_value("status") != "invoiced") { return "ERROR: Status of the timesheet must be 'invoiced' to Create Transactions.\n The status is currently: " . $this->get_value("status"); } else { if ($this->get_value("recipient_tfID") == "") { return "ERROR: There is no recipient Tagged Fund to credit for this timesheet.\n Go to Tools -> New Tagged Fund, add a new TF and add the owner. Then go\n to People -> Select the user and set their Preferred Payment TF."; } else { if (!$cost_centre || $cost_centre == 0) { return "ERROR: There is no cost centre associated with the project."; } } } $taxName = config::get_config_item("taxName"); $taxPercent = config::get_config_item("taxPercent"); $taxTfID = config::get_config_item("taxTfID"); $taxPercentDivisor = $taxPercent / 100 + 1; $recipient_tfID = $this->get_value("recipient_tfID"); $timeSheetRecipients = $project->get_timeSheetRecipients(); $rtn = array(); // This is just for internal transactions if ($_POST["create_transactions_default"] && $this->pay_info["total_customerBilledDollars"] == 0) { $this->pay_info["total_customerBilledDollars_minus_gst"] = $this->pay_info["total_dollars"]; // 1. Credit Employee TF $product = "Timesheet #" . $this->get_id() . " for " . $projectName . " (" . $this->pay_info["summary_unit_totals"] . ")"; $rtn[$product] = $this->createTransaction($product, $this->pay_info["total_dollars"], $recipient_tfID, "timesheet", $status); // 2. Payment Insurance // removed } else { if ($_POST["create_transactions_default"]) { /* This was previously named "Simple" transactions. Ho ho. On the Project page we care about these following variables: - Client Billed At $amount eg: $121 - The projectPersons rate for this project eg: $50; $121 after gst == $110 cyber get 28.5% of $110 djk get $50 commissions whatever is left of the $110 goes to the 0% commissions */ // 1. Credit TAX/GST Cost Centre $product = $taxName . " " . $taxPercent . "% for timesheet #" . $this->get_id(); $rtn[$product] = $this->createTransaction($product, $this->pay_info["total_customerBilledDollars"] - $this->pay_info["total_customerBilledDollars_minus_gst"], $taxTfID, "tax", $status); // 3. Credit Employee TF $product = "Timesheet #" . $this->get_id() . " for " . $projectName . " (" . $this->pay_info["summary_unit_totals"] . ")"; $rtn[$product] = $this->createTransaction($product, $this->pay_info["total_dollars"], $recipient_tfID, "timesheet", $status); // 4. Credit Project Commissions $db->query("SELECT * FROM projectCommissionPerson where projectID = %d ORDER BY commissionPercent DESC", $this->get_value("projectID")); while ($db->next_record()) { if ($db->f("commissionPercent") > 0) { $product = "Commission " . $db->f("commissionPercent") . "% of " . $this->pay_info["currency"] . $this->pay_info["total_customerBilledDollars_minus_gst"]; $product .= " from timesheet #" . $this->get_id() . ". Project: " . $projectName; $amount = $this->pay_info["total_customerBilledDollars_minus_gst"] * ($db->f("commissionPercent") / 100); $rtn[$product] = $this->createTransaction($product, $amount, $db->f("tfID"), "commission", $status); // Suck up the rest of funds if it is a special zero % commission } else { if ($db->f("commissionPercent") == 0) { $amount = $this->pay_info["total_customerBilledDollars_minus_gst"] - $this->get_amount_so_far(); $amount < 0 and $amount = 0; // If the 0% commission is for the company tf, dump it in the company tf if ($db->f("tfID") == $company_tfID) { $product = "Commission Remaining from timesheet #" . $this->get_id() . ". Project: " . $projectName; $rtn[$product] = $this->createTransaction($product, $amount, $db->f("tfID"), "commission"); } else { // If it's cyber do a 50/50 split with the commission tf and the company if (config::for_cyber()) { $amount = $amount / 2; $product = "Commission Remaining from timesheet #" . $this->get_id() . ". Project: " . $projectName; $rtn[$product] = $this->createTransaction($product, $amount, $db->f("tfID"), "commission"); $rtn[$product] = $this->createTransaction($product, $amount, $company_tfID, "commission", $status); // 50/50 } else { $product = "Commission Remaining from timesheet #" . $this->get_id() . ". Project: " . $projectName; $rtn[$product] = $this->createTransaction($product, $amount, $db->f("tfID"), "commission"); } } } } } } } foreach ($rtn as $error => $v) { $v != 1 and $errmsg .= "<br>FAILED: " . $error; } if ($errmsg) { $this->destroyTransactions(); $rtnmsg .= "<br>Failed to create transactions... " . $errmsg; } return $rtnmsg; }
function move_forwards() { $current_user =& singleton("current_user"); global $TPL; $status = $this->get_value("status"); $db = new db_alloc(); if ($this->get_value("clientID")) { $c = $this->get_foreign_object("client"); $extra = " for " . $c->get_value("clientName"); $taskDesc[] = ""; } $taskname1 = "Sale " . $this->get_id() . ": raise an invoice" . $extra; $taskname2 = "Sale " . $this->get_id() . ": place an order to the supplier"; $taskname3 = "Sale " . $this->get_id() . ": pay the supplier"; $taskname4 = "Sale " . $this->get_id() . ": deliver the goods / action the work"; $cyberadmin = 59; $taskDesc[] = "Sale items:"; $taskDesc[] = ""; foreach ((array) $this->get_productSaleItems() as $psiID => $psi_row) { $p = new product(); $p->set_id($psi_row["productID"]); $taskDesc[] = " " . page::money($psi_row["sellPriceCurrencyTypeID"], $psi_row["sellPrice"], "%S%mo") . " for " . $psi_row["quantity"] . " x " . $p->get_name(); $hasItems = true; } if (!$hasItems) { return alloc_error("No sale items have been added."); } $amounts = $this->get_amounts(); $taskDesc[] = ""; $taskDesc[] = "Total: " . $amounts["total_sellPrice"]; $taskDesc[] = "Total inc " . config::get_config_item("taxName") . ": " . $amounts["total_sellPrice_plus_gst"]; $taskDesc[] = ""; $taskDesc[] = "Refer to the sale in alloc for up-to-date information:"; $taskDesc[] = config::get_config_item("allocURL") . "sale/productSale.php?productSaleID=" . $this->get_id(); $taskDesc = implode("\n", $taskDesc); if ($status == "edit") { $this->set_value("status", "allocate"); $items = $this->get_productSaleItems(); foreach ($items as $r) { $psi = new productSaleItem(); $psi->set_id($r["productSaleItemID"]); $psi->select(); if (!$db->qr("SELECT transactionID FROM transaction WHERE productSaleItemID = %d", $psi->get_id())) { $psi->create_transactions(); } } } else { if ($status == "allocate") { $this->set_value("status", "admin"); // 1. from salesperson to admin $q = prepare("SELECT * FROM task WHERE projectID = %d AND taskName = '%s'", $cyberadmin, $taskname1); if (config::for_cyber() && !$db->qr($q)) { $task = new task(); $task->set_value("projectID", $cyberadmin); // Cyber Admin Project $task->set_value("taskName", $taskname1); $task->set_value("managerID", $this->get_value("personID")); // salesperson $task->set_value("personID", 67); // Cyber Support people (jane) $task->set_value("priority", 3); $task->set_value("taskTypeID", "Task"); $task->set_value("taskDescription", $taskDesc); $task->set_value("dateTargetStart", date("Y-m-d")); $task->set_value("dateTargetCompletion", date("Y-m-d", date("U") + 60 * 60 * 24 * 7)); $task->save(); $TPL["message_good"][] = "Task created: " . $task->get_id() . " " . $task->get_value("taskName"); $p1 = new person(); $p1->set_id($this->get_value("personID")); $p1->select(); $p2 = new person(); $p2->set_id(67); $p2->select(); $recipients[$p1->get_value("emailAddress")] = array("name" => $p1->get_name(), "addIP" => true, "internal" => true); $recipients[$p2->get_value("emailAddress")] = array("name" => $p2->get_name(), "addIP" => true, "internal" => true); $comment = $p2->get_name() . ",\n\n" . $taskname1 . "\n\n" . $taskDesc; $commentID = comment::add_comment("task", $task->get_id(), $comment, "task", $task->get_id()); $emailRecipients = comment::add_interested_parties($commentID, null, $recipients); // Re-email the comment out, including any attachments if (!comment::send_comment($commentID, $emailRecipients)) { alloc_error("Email failed to send."); } else { $TPL["message_good"][] = "Emailed task comment to " . $p1->get_value("emailAddress") . ", " . $p2->get_value("emailAddress") . "."; } } } else { if ($status == "admin" && $this->have_perm(PERM_APPROVE_PRODUCT_TRANSACTIONS)) { $this->set_value("status", "finished"); if ($_REQUEST["changeTransactionStatus"]) { $rows = $this->get_productSaleItems(); foreach ($rows as $row) { $ids[] = $row["productSaleItemID"]; } if ($ids) { $q = prepare("UPDATE transaction SET status = '%s' WHERE productSaleItemID in (%s)", $_REQUEST["changeTransactionStatus"], $ids); $db = new db_alloc(); $db->query($q); } } // 2. from admin to salesperson $q = prepare("SELECT * FROM task WHERE projectID = %d AND taskName = '%s'", $cyberadmin, $taskname2); if (config::for_cyber() && !$db->qr($q)) { $task = new task(); $task->set_value("projectID", $cyberadmin); // Cyber Admin Project $task->set_value("taskName", $taskname2); $task->set_value("managerID", 67); // Cyber Support people (jane) $task->set_value("personID", $this->get_value("personID")); // salesperson $task->set_value("priority", 3); $task->set_value("taskTypeID", "Task"); $task->set_value("taskDescription", $taskDesc); $task->set_value("dateTargetStart", date("Y-m-d")); $task->set_value("dateTargetCompletion", date("Y-m-d", date("U") + 60 * 60 * 24 * 7)); $task->save(); $q = prepare("SELECT * FROM task WHERE projectID = %d AND taskName = '%s'", $cyberadmin, $taskname1); $rai_row = $db->qr($q); if ($rai_row) { $task->add_pending_tasks($rai_row["taskID"]); } $order_the_hardware_taskID = $task->get_id(); $TPL["message_good"][] = "Task created: " . $task->get_id() . " " . $task->get_value("taskName"); $task->add_notification(3, 1, "Task " . $task->get_id() . " " . $taskname2, "Task status moved from pending to open.", array(array("field" => "metaPersonID", "who" => -2))); } // 3. from salesperson to admin $q = prepare("SELECT * FROM task WHERE projectID = %d AND taskName = '%s'", $cyberadmin, $taskname3); if (config::for_cyber() && !$db->qr($q)) { $task = new task(); $task->set_value("projectID", $cyberadmin); // Cyber Admin Project $task->set_value("taskName", $taskname3); $task->set_value("managerID", $this->get_value("personID")); // salesperson $task->set_value("personID", 67); // Cyber Support people (jane) $task->set_value("priority", 3); $task->set_value("taskTypeID", "Task"); $task->set_value("taskDescription", $taskDesc); $task->set_value("dateTargetStart", date("Y-m-d")); $task->set_value("dateTargetCompletion", date("Y-m-d", date("U") + 60 * 60 * 24 * 7)); $task->save(); $task->add_pending_tasks($order_the_hardware_taskID); $pay_the_supplier_taskID = $task->get_id(); $TPL["message_good"][] = "Task created: " . $task->get_id() . " " . $task->get_value("taskName"); $task->add_notification(3, 1, "Task " . $task->get_id() . " " . $taskname3, "Task status moved from pending to open.", array(array("field" => "metaPersonID", "who" => -2))); } // 4. from admin to salesperson $q = prepare("SELECT * FROM task WHERE projectID = %d AND taskName = '%s'", $cyberadmin, $taskname4); if (config::for_cyber() && !$db->qr($q)) { $task = new task(); $task->set_value("projectID", $cyberadmin); // Cyber Admin Project $task->set_value("taskName", $taskname4); $task->set_value("managerID", 67); // Cyber Support people $task->set_value("personID", $this->get_value("personID")); // salesperson $task->set_value("priority", 3); $task->set_value("taskTypeID", "Task"); $task->set_value("taskDescription", $taskDesc); $task->set_value("dateTargetStart", date("Y-m-d")); $task->set_value("dateTargetCompletion", date("Y-m-d", date("U") + 60 * 60 * 24 * 7)); $task->save(); $task->add_pending_tasks($pay_the_supplier_taskID); $TPL["message_good"][] = "Task created: " . $task->get_id() . " " . $task->get_value("taskName"); $task->add_notification(3, 1, "Task " . $task->get_id() . " " . $taskname4, "Task status moved from pending to open.", array(array("field" => "metaPersonID", "who" => -2))); } } } } }
public static function get_list($_FORM) { $current_user =& singleton("current_user"); global $TPL; /* * This is the definitive method of getting a list of transactions that need a sophisticated level of filtering * */ $_FORM["tfIDs"] = transaction::reduce_tfs($_FORM); // Non-admin users must specify a valid TF if (!$current_user->have_role("admin") && !$_FORM["tfIDs"]) { return; } $filter = transaction::get_list_filter($_FORM); $debug = $_FORM["debug"]; $debug and print "\n<pre>_FORM: " . print_r($_FORM, 1) . "</pre>"; $debug and print "\n<pre>filter: " . print_r($filter, 1) . "</pre>"; $_FORM["return"] or $_FORM["return"] = "html"; $filter["prevBalance"] and $filter2[] = $filter["prevBalance"]; $filter["tfIDs"] and $filter2[] = $filter["tfIDs"]; $filter2 and $filter2[] = " (status = 'approved') "; unset($filter["prevBalance"]); if (is_array($filter2) && count($filter2)) { $filter2 = " WHERE " . implode(" AND ", $filter2); } if (is_array($filter) && count($filter)) { $filter = " WHERE " . implode(" AND ", $filter); } $_FORM["sortTransactions"] or $_FORM["sortTransactions"] = "transactionDate"; $order_by = "ORDER BY " . $_FORM["sortTransactions"]; // Determine opening balance if (is_array($_FORM['tfIDs']) && count($_FORM['tfIDs'])) { $q = prepare("SELECT SUM( IF(fromTfID IN (%s),-amount,amount) * pow(10,-currencyType.numberToBasic) * exchangeRate) AS balance\n FROM transaction \n LEFT JOIN currencyType ON currencyType.currencyTypeID = transaction.currencyTypeID\n " . $filter2, $_FORM['tfIDs']); $debug and print "\n<br>QUERY: " . $q; $db = new db_alloc(); $db->query($q); $db->row(); $_FORM["opening_balance"] = $db->f("balance"); $running_balance = $db->f("balance"); } $q = "SELECT *, \n (amount * pow(10,-currencyType.numberToBasic)) as amount1,\n (amount * pow(10,-currencyType.numberToBasic) * exchangeRate) as amount2,\n if(transactionModifiedTime,transactionModifiedTime,transactionCreatedTime) AS transactionSortDate,\n tf1.tfName as fromTfName,\n tf2.tfName as tfName\n FROM transaction \n LEFT JOIN currencyType ON currencyType.currencyTypeID = transaction.currencyTypeID\n LEFT JOIN tf tf1 ON transaction.fromTfID = tf1.tfID\n LEFT JOIN tf tf2 ON transaction.tfID = tf2.tfID\n " . $filter . " \n " . $order_by; $debug and print "\n<br>QUERY2: " . $q; $db = new db_alloc(); $db->query($q); $for_cyber = config::for_cyber(); while ($row = $db->next_record()) { #echo "<pre>".print_r($row,1)."</pre>"; $i++; $t = new transaction(); if (!$t->read_db_record($db)) { continue; } $print = true; // If the destination of this TF is not the current TfID, then invert the $amount $amount = $row["amount2"]; if (!in_array($row["tfID"], (array) $_FORM["tfIDs"])) { $amount = -$amount; $row["amount1"] = -$row["amount1"]; } $row["amount"] = $amount; $row["transactionURL"] = $t->get_url(); $row["transactionName"] = $t->get_name($_FORM); $row["transactionLink"] = $t->get_transaction_link($_FORM); $row["transactionTypeLink"] = $t->get_transaction_type_link() or $row["transactionTypeLink"] = $row["transactionType"]; $row["transactionSortDate"] = format_date("Y-m-d", $row["transactionSortDate"]); $row["fromTfIDLink"] = "<a href=\"" . $TPL["url_alloc_transactionList"] . "tfID=" . $row["fromTfID"] . "\">" . page::htmlentities($row["fromTfName"]) . "</a>"; $row["tfIDLink"] = "<a href=\"" . $TPL["url_alloc_transactionList"] . "tfID=" . $row["tfID"] . "\">" . page::htmlentities($row["tfName"]) . "</a>"; if ($t->get_value("status") == "approved") { $running_balance += $amount; $row["running_balance"] = page::money(config::get_config_item("currency"), $running_balance, "%m %c"); } if ($amount > 0) { $row["amount_positive"] = page::money($row["currencyTypeID"], $row["amount1"], "%m %c"); $total_amount_positive += $amount; } else { $row["amount_negative"] = page::money($row["currencyTypeID"], $row["amount1"], "%m %c"); $total_amount_negative += $amount; } // Cyber only hackery for ext ref field on product sales if ($for_cyber && $row["productSaleID"]) { $ps = new productSale(); $ps->set_id($row["productSaleID"]); if ($ps->select()) { $ps->get_value("extRef") and $row["product"] .= " (Ext ref: " . $ps->get_value("extRef") . ")"; } } $transactions[$row["transactionID"]] = $row; } $_FORM["total_amount_positive"] = page::money(config::get_config_item("currency"), $total_amount_positive, "%s%m %c"); $_FORM["total_amount_negative"] = page::money(config::get_config_item("currency"), $total_amount_negative, "%s%m %c"); $_FORM["running_balance"] = page::money(config::get_config_item("currency"), $running_balance, "%s%m %c"); return array("totals" => $_FORM, "rows" => (array) $transactions); }