. ***********************************************************************/ function add_wo_costing($workorder_id, $cost_type, $trans_type, $trans_no, $factor=1) { $sql = "INSERT INTO ".TB_PREF."wo_costing (workorder_id, cost_type, trans_type, trans_no, factor) VALUES (".db_escape($workorder_id)."," .db_escape($cost_type).",".db_escape($trans_type)."," .db_escape($trans_no).",".db_escape($factor).")"; db_query($sql, "could not add work order costing"); } function get_wo_costing($workorder_id) { $sql="SELECT * FROM ".TB_PREF."wo_costing cost, ".TB_PREF."journal gl WHERE cost.trans_type=gl.type AND cost.trans_no=gl.trans_no AND workorder_id=".db_escape($workorder_id); return db_query($sql, "could not get work order costing"); } function delete_wo_costing($trans_type, $trans_no) { $sql="DELETE FROM ".TB_PREF."wo_costing WHERE trans_type=".db_escape($trans_type) ." AND trans_no=".db_escape($trans_no); db_query($sql, "could not delete work order costing"); } /* Updates average material cost for item. */ function update_material_cost($stock_id, $qty, $unit_cost, $date) { global $Refs; $product = get_item($stock_id); $avg_cost = $product['material_cost']; $qoh = get_qoh_on_date($stock_id, null, $date); // unit_cost*qty is already posted on inventory GL /* if ($qoh > 0) { if ($qty<0) $qty_done = max(-$qoh, $qty); else $qty_done = $qty; } else { if ($qty>0) $qty_done = max($qoh+$qty, 0); else $qty_done = 0; } $qty_delayed = $qty-$qty_done; */ if ($qoh < 0) { $qty_delayed = min(-$qoh, $qty); } else { $qty_delayed = 0; } $qty_new = $qty - $qty_delayed; if ($qty_delayed > 0 && ($unit_cost != $avg_cost)) { // post $qty_delayed*($avg_cost-$unit_cost) $diff = $qty_delayed*($unit_cost-$avg_cost); $stock_gl_code = get_item($stock_id); $dec = user_price_dec(); $old_cost = -round2($avg_cost, $dec); $new_cost = -round2($unit_cost, $dec); $cart = new items_cart(ST_COSTUPDATE); $cart->tran_date = $cart->doc_date = $cart->event_date = $date; if (!is_date_in_fiscalyear($cart->tran_date)) $cart->tran_date = end_fiscalyear(); $cart->reference = $Refs->get_next(ST_COSTUPDATE, null, $cart->tran_date, $date); $cart->memo_ = sprintf(_("COGS changed from %s to %s for %d %s of '%s'"), $avg_cost, $unit_cost, $qty_delayed, $item['units'], $stock_id); $cart->add_gl_item($item["cogs_account"], $item["dimension_id"], $item["dimension2_id"], -$diff); $cart->add_gl_item($item["inventory_account"], 0, 0, $diff); write_journal_entries($cart); } if ($qty > 0 && ($qoh != -$qty)) $avg_cost = ($avg_cost*($qoh+$qty_delayed)+$unit_cost*$qty_new)/($qoh+$qty); $sql = "UPDATE ".TB_PREF."stock_master SET material_cost=".db_escape($avg_cost)." WHERE stock_id=".db_escape($stock_id); db_query($sql,"The cost details for the inventory item could not be updated"); } function add_issue_cost($stock_id, $qty, $date_, $costs, $adj_only=false) { if ($qty != 0) $costs /= $qty; $sql = "SELECT material_cost FROM ".TB_PREF."stock_master WHERE stock_id = " .db_escape($stock_id); $result = db_query($sql); $myrow = db_fetch($result); $material_cost = $myrow['material_cost']; $qoh = get_qoh_on_date($stock_id); if ($qoh < 0) $qoh = 0; if ($adj_only) { if ($qoh>0) $material_cost = ($qoh * $material_cost + $costs) / $qoh; else // Journal Entry if QOH is 0/negative { global $Refs; $id = get_next_trans_no(ST_JOURNAL); $ref = $Refs->get_next(ST_JOURNAL, null, $date_); add_journal(ST_JOURNAL, $id, $costs, $date_, get_company_currency(), $ref); $stock_gl_code = get_stock_gl_code($stock_id); $memo = "WO Issue settlement JV for zero/negative respository of ".$stock_id; //Reverse the inventory effect if $qoh <=0 add_gl_trans_std_cost(ST_JOURNAL, $id, $date_, $stock_gl_code["inventory_account"], $stock_gl_code['dimension_id'], $stock_gl_code['dimension2_id'], $memo, -$costs); //GL Posting to inventory adjustment account add_gl_trans_std_cost(ST_JOURNAL, $id, $date_, $stock_gl_code["assembly_account"], $stock_gl_code['dimension_id'], $stock_gl_code['dimension2_id'], $memo, $costs); add_audit_trail(ST_JOURNAL, $id, $date_); add_comments(ST_JOURNAL, $id, $date_, $memo); $Refs->save(ST_JOURNAL, $id, $ref); if ($qty != 0) $material_cost = $costs / $qty; } } else { if ($qoh + $qty != 0) $material_cost = ($qoh * $material_cost + $qty * $costs) / ($qoh + $qty); } $sql = "UPDATE ".TB_PREF."stock_master SET material_cost=material_cost+" .db_escape($material_cost) ." WHERE stock_id=".db_escape($stock_id); db_query($sql,"The cost details for the inventory item could not be updated"); } /* Create journal entry for WO related costs. */ function add_wo_costs_journal($wo_id, $amount, $cost_type, $cr_acc, $date, $dim1=0, $dim2=0, $memo = null, $ref= null) { //-------- this should be done by single call to write_journal_entries() using items_cart() // global $Refs, $wo_cost_types; begin_transaction(); $journal_id = get_next_trans_no(ST_JOURNAL); $wo = get_work_order($wo_id); if (!$ref) $ref = $Refs->get_next(ST_JOURNAL, null, $date); add_gl_trans_std_cost(ST_JOURNAL, $journal_id, $date, $cr_acc, 0, 0, $wo_cost_types[$cost_type], -$amount); $is_bank_to = is_bank_account($cr_acc); if ($is_bank_to) { add_bank_trans(ST_JOURNAL, $journal_id, $is_bank_to, "", $date, -$amount, PT_WORKORDER, $wo_id, get_company_currency(), "Cannot insert a destination bank transaction"); } add_journal(ST_JOURNAL, $journal_id, $amount, $date, get_company_currency(), $ref); add_gl_trans_std_cost(ST_JOURNAL, $journal_id, $date, $wo['assembly_account'], $dim1, $dim2, $wo_cost_types[$cost_type], $amount); $wo = get_work_order($wo_id); $wip = $wo['assembly_account']; $Refs->save(ST_JOURNAL, $journal_id, $ref); add_wo_costing($wo_id, $cost_type, ST_JOURNAL, $journal_id); add_comments(ST_JOURNAL, $journal_id, $date, $memo); add_audit_trail(ST_JOURNAL, $journal_id, $date); commit_transaction(); } /* Process component usage: generate and post stock move, update average component cost. */ function work_order_production_gl($woid, $stock_id, $quantity, $date_, $rcv_no) { $result = get_wo_requirements($woid); // credit all the components $total_cost = 0; while ($bom_item = db_fetch($result)) { update_wo_requirement_issued($bom_item['id'], $bom_item["units_req"] * $quantity, $bom_item["ComponentCost"]); // insert a -ve stock move for each item add_stock_move(ST_MANURECEIVE, $bom_item["stock_id"], $rcv_no, $bom_item["loc_code"], $date_, "", -$bom_item["units_req"] * $quantity, $bom_item["ComponentCost"], 0); if (!is_service($bom_item["mb_flag"])) $ivaccount = $bom_item["inventory_account"]; else $ivaccount = $bom_item["cogs_account"]; $memo = $date_.": ".$bom_item["units_req"] ." * ".$bom_item["description"]; $total_cost += add_gl_trans_std_cost(ST_MANURECEIVE, $rcv_no, $date_, $ivaccount, 0, 0, $memo, -$bom_item["ComponentCost"] * $bom_item["units_req"] * $quantity); } $wo = get_work_order($woid); add_gl_trans_std_cost(ST_MANURECEIVE, $rcv_no, $date_, $wo['assembly_account'], 0, 0, $memo, -$total_cost); } function void_wo_costing($wo_id) { $res = get_wo_costing($wo_id); while($row = db_fetch($res)) { // void any related gl trans void_gl_trans($row['trans_type'], $row['trans_no'], true); } $sql = "DELETE FROM ".TB_PREF."wo_costing WHERE workorder_id=".db_escape($wo_id); db_query($sql, "could not delete work order costing"); }