3 * Table Definition for custinfo
5 require_once 'DB/DataObject.php';
7 class Pman_Xtuple_DataObjects_Custinfo extends DB_DataObject
10 /* the code below is auto generated do not remove the above tag */
12 public $__table = 'custinfo'; // table name
13 public $cust_id; // int4(4) not_null default_nextval%28%28cust_cust_id_seq%29%3A%3Aregclass%29 primary_key
14 public $cust_active; // bool(1) not_null
15 public $cust_custtype_id; // int4(4)
16 public $cust_salesrep_id; // int4(4)
17 public $cust_commprcnt; // numeric(-1)
18 public $cust_name; // text(-1)
19 public $cust_creditlmt; // int4(4)
20 public $cust_creditrating; // text(-1)
21 public $cust_financecharge; // bool(1)
22 public $cust_backorder; // bool(1) not_null
23 public $cust_partialship; // bool(1) not_null
24 public $cust_terms_id; // int4(4)
25 public $cust_discntprcnt; // numeric(-1) not_null
26 public $cust_balmethod; // bpchar(-1) not_null
27 public $cust_ffshipto; // bool(1) not_null
28 public $cust_shipform_id; // int4(4)
29 public $cust_shipvia; // text(-1)
30 public $cust_blanketpos; // bool(1) not_null
31 public $cust_shipchrg_id; // int4(4) not_null
32 public $cust_creditstatus; // bpchar(-1) not_null
33 public $cust_comments; // text(-1)
34 public $cust_ffbillto; // bool(1) not_null
35 public $cust_usespos; // bool(1) not_null
36 public $cust_number; // text(-1) unique_key unique_key
37 public $cust_dateadded; // date(4) default_%28now%29%3A%3Adate
38 public $cust_exported; // bool(1) default_false
39 public $cust_emaildelivery; // bool(1) default_false
40 public $cust_ediemail; // text(-1)
41 public $cust_edisubject; // text(-1)
42 public $cust_edifilename; // text(-1)
43 public $cust_ediemailbody; // text(-1)
44 public $cust_autoupdatestatus; // bool(1) not_null
45 public $cust_autoholdorders; // bool(1) not_null
46 public $cust_edicc; // text(-1)
47 public $cust_ediprofile_id; // int4(4)
48 public $cust_preferred_warehous_id; // int4(4) not_null default_%28-1%29
49 public $cust_curr_id; // int4(4) default_basecurrid%28%29
50 public $cust_creditlmt_curr_id; // int4(4) default_basecurrid%28%29
51 public $cust_cntct_id; // int4(4)
52 public $cust_corrcntct_id; // int4(4)
53 public $cust_soemaildelivery; // bool(1) default_false
54 public $cust_soediemail; // text(-1)
55 public $cust_soedisubject; // text(-1)
56 public $cust_soedifilename; // text(-1)
57 public $cust_soediemailbody; // text(-1)
58 public $cust_soedicc; // text(-1)
59 public $cust_soediprofile_id; // int4(4)
60 public $cust_gracedays; // int4(4)
61 public $cust_ediemailhtml; // bool(1) not_null default_false
62 public $cust_soediemailhtml; // bool(1) not_null default_false
63 public $cust_taxzone_id; // int4(4)
65 public $cust_login_email;
69 * Getter / Setter for $cust_creditlmt_curr_id
71 * @param mixed (optional) value to assign
74 public function creditlmt_curr() {
75 return func_num_args() ? $this->link('cust_creditlmt_curr_id', func_get_arg(0)) : $this->link('cust_creditlmt_curr_id');
79 * Getter / Setter for $cust_curr_id
81 * @param mixed (optional) value to assign
84 public function curr() {
85 return func_num_args() ? $this->link('cust_curr_id', func_get_arg(0)) : $this->link('cust_curr_id');
89 * Getter / Setter for $cust_cntct_id
91 * @param mixed (optional) value to assign
94 public function cntct() {
95 return func_num_args() ? $this->link('cust_cntct_id', func_get_arg(0)) : $this->link('cust_cntct_id');
99 * Getter / Setter for $cust_corrcntct_id
101 * @param mixed (optional) value to assign
104 public function corrcntct() {
105 return func_num_args() ? $this->link('cust_corrcntct_id', func_get_arg(0)) : $this->link('cust_corrcntct_id');
109 * Getter / Setter for $cust_custtype_id
111 * @param mixed (optional) value to assign
114 public function custtype() {
115 return func_num_args() ? $this->link('cust_custtype_id', func_get_arg(0)) : $this->link('cust_custtype_id');
119 * Getter / Setter for $cust_salesrep_id
121 * @param mixed (optional) value to assign
124 public function salesrep() {
125 return func_num_args() ? $this->link('cust_salesrep_id', func_get_arg(0)) : $this->link('cust_salesrep_id');
129 * Getter / Setter for $cust_shipform_id
131 * @param mixed (optional) value to assign
134 public function shipform() {
135 return func_num_args() ? $this->link('cust_shipform_id', func_get_arg(0)) : $this->link('cust_shipform_id');
139 * Getter / Setter for $cust_taxzone_id
141 * @param mixed (optional) value to assign
144 public function taxzone() {
145 return func_num_args() ? $this->link('cust_taxzone_id', func_get_arg(0)) : $this->link('cust_taxzone_id');
149 * Getter / Setter for $cust_terms_id
151 * @param mixed (optional) value to assign
154 public function terms() {
155 return func_num_args() ? $this->link('cust_terms_id', func_get_arg(0)) : $this->link('cust_terms_id');
159 /* the code above is auto generated do not remove the tag below */
162 public function crmacct() {
163 $c = DB_DataObject::factory('crmacct');
164 $c->get('crmacct_cust_id', $this->cust_id);
168 function applyFilters($q, $au, $roo)
170 if(isset($q['_filterTop'])){
171 $top = $this->filterTop();
175 if (isset($q['_with_lastyear_total'])) {
177 // this is the figure that displays next to the customer, the number of sales of selected brand if _with_lastyear total is not empty..
178 // it should be based on the selected brand.
181 if(!empty($q['_charass_brand_value'])){
182 $brand_ids = implode(',', DB_DataObject::factory('charass')->lookupIds('I', 'BRAND', $q['_charass_brand_value']));
183 $brandStr = "AND invcitem_item_id IN ({$brand_ids})";
186 if(!empty($q['_charass_group_value'])){
187 $group_ids = implode(',', DB_DataObject::factory('charass')->lookupIds('I', 'PRODUCTGROUP', $q['_charass_group_value']));
188 $groupStr = "AND invcitem_item_id IN ({$group_ids})";
195 ROUND(COALESCE(SUM(invcitem_billed),0))
201 invcitem_invchead_id = invchead_id
205 invcitem_item_id = itemsite_item_id
207 invchead_cust_id = cust_id
209 extract(year from invchead_invcdate) = extract(year from NOW() - INTERVAL '1 YEAR')
211 itemsite_stocked = TRUE
217 $this->whereAddIn('cust_id', $this->filterTop(), 'int');
219 $this->orderBy("lastyear_total DESC");
222 if (isseT($_REQUEST['_report'])) {
223 $this->applyFiltersReport($roo, $_REQUEST['_report'], $_REQUEST['date_from'],$_REQUEST['date_to'] );
224 return $this->jerr("oops");
227 if (!empty($q['search']['_country'])) {
228 $this->whereAdd("join_cust_addr_id.addr_country LIKE '{$this->escape($q['search']['_country'])}%'");
231 if (!empty($q['query']['cust_name'])) {
232 $v = $this->escape($q['query']['cust_name']);
233 $this->whereAdd("cust_name ILIKE '%$v%' OR cust_number ILIKE '%$v%'");
235 if (!empty($q['search']['cust_name'])) {
236 $v = $this->escape($q['search']['cust_name']);
237 $this->whereAdd("cust_name ILIKE '%$v%' OR cust_number ILIKE '%$v%'");
239 if (!empty($q['query']['cust_name_begin'])) {
240 $v = $this->escape($q['query']['cust_name_begin']);
241 $this->whereAdd("cust_name ILIKE '$v%' OR cust_number ILIKE '$v%' ");
244 if (!empty($q['search']['_mix'])) {
245 $v = $this->escape($q['search']['_mix']);
247 cust_name ILIKE '%$v%'
249 cust_number ILIKE '%$v%'
251 join_cust_cntct_id_cntct_id.cntct_name ILIKE '%$v%'
253 join_cust_cntct_id_cntct_id.cntct_phone ILIKE '%$v%'
255 join_cust_cntct_id_cntct_id.cntct_phone2 ILIKE '%$v%'
259 if (!empty($q['search']['orders_since'])) {
260 $dt = date('Y-m-d', strtotime($q['search']['orders_since']));
261 $this->whereAdd("cust_id IN (SELECT cohead_cust_id FROM cohead where cohead_orderdate > ' $dt')");
263 if (!empty($q['search']['no_orders_since'])) {
264 $dt = date('Y-m-d', strtotime($q['search']['no_orders_since']));
265 $this->whereAdd("cust_id NOT IN (SELECT cohead_cust_id FROM cohead where cohead_orderdate > ' $dt')");
268 if (!empty($q['search']['with_orders_since'])) {
269 $this->selectAdd("(SELECT max(cohead_orderdate ) FROM cohead where cohead_cust_id = cust_id) as last_order");
271 if (!empty($q['search']['with_address'])) {
272 $this->selectAddAddresses();
274 if (!empty($q['cust_aropen_active'])) {
275 $this->whereAdd('cust_id IN (SELECT distinct(aropen_cust_id) FROM aropen)');
279 if (!empty($q['_with_char'])) {
280 $ch = DB_DAtaObject::Factory('char');
281 $ch->char_customers = 1;
283 if (!$ch->count() < 2) {
287 while ($ch->fetch()) {
288 $nm = 'cust_char_' . strtolower(preg_replace('/[^a-z]+/i','_', $ch->char_name));
290 if (!empty($q[$nm])) {
292 charass_getvalue('C', cust_id, '{$ch->char_name}') = '{$this->escape($q[$nm])}'
298 charass_getvalue('C', cust_id, '{$ch->char_name}') as $nm
300 if (!empty($q['sort']) && $q['sort'] == $nm) {
301 $dir = (empty($q['dir']) || $q['dir'] == 'ASC') ? 'ASC' : 'DESC';
302 $this->orderBy("charass_getvalue('C', cust_id, '{$ch->char_name}') $dir");
308 if(isset($q['_with_group_data'])){
309 $this->autoJoinCoheadLastSale();
312 if (!empty($q['sort']) && $q['sort'] == 'cntct_addr_country') {
313 $dir = (empty($q['dir']) || $q['dir'] == 'ASC') ? 'ASC' : 'DESC';
314 $this->orderBy(" cntct_addr_country $dir ");
317 if (!empty($q['search']['with_balance'])) {
318 // this exclude cash receipts which have not been applied.
319 //DB_DataObject::DebugLevel(1);
327 CASE WHEN (aropen_doctype IN ('C', 'R')) THEN
328 (aropen_amount - aropen_paid) * -1.0
330 (aropen_amount - aropen_paid)
338 aropen_cust_id = cust_id
347 $l = DB_DataObject::factory('location')->defaultConfigLocation();
348 if ($l->location_id) {
350 {$l->pid()} AS default_location_id,
351 '{$this->escape($l->location_name)}' AS default_location_name
355 0 AS default_location_id,
356 '' AS default_location_name
360 (SELECT ipsass_ipshead_id FROM ipsass WHERE ipsass_cust_id = cust_id ORDER BY ipsass_id ASC LIMIT 1) as ipshead_id,
361 (SELECT ipshead_name FROM ipshead WHERE ipshead_id =
362 (SELECT ipsass_ipshead_id FROM ipsass WHERE ipsass_cust_id = cust_id ORDER BY ipsass_id ASC LIMIT 1)
369 function autoJoinCoheadLastSale()
373 cohead AS join_cust_cohead_id
375 join_cust_cohead_id.cohead_cust_id = cust_id
377 join_cust_cohead_id.cohead_id = (SELECT cohead_id FROM cohead WHERE cohead_cust_id = cust_id ORDER BY cohead_orderdate DESC LIMIT 1)
380 $add = DB_DataObject::Factory('cohead');
381 $this->selectAs($add, 'cust_%s', 'join_cust_cohead_id');
384 function selectAddAddresses()
386 // not sure where this is used. -- looks like only customertab..
387 //DB_DAtaObject::DebugLevel(1);
391 addr join_cust_addr_id
394 join_cust_addr_id.addr_id = join_cust_cntct_id_cntct_id.cntct_addr_id";
396 $add = DB_DataObject::Factory('addr');
397 $this->selectAs($add, 'cntct_%s', 'join_cust_addr_id');
403 function onUpdate($old,$req,$roo)
405 // update includes information on ship addresses.
407 // we need to sync this up with shiptoinfo..
409 if (isset($req['shiplist'])) {
410 $ar = explode(',', $req['shiplist']);
411 $this->updateShipList($ar);
414 if (isset($req['ipshead_id'])) {
415 $this->updatePriceList($req['ipshead_id']);
418 $this->updateCharass($req);
420 if(($this->cust_login_email != $old->cust_login_email) || $this->cust_cntct_id != $old->cust_cntct_id){
421 $this->updateCntct($roo);
425 function char($str) {
427 $ca = DB_DAtaObject::factory('charass');
432 '".$this->escape($str). "'
435 return empty($ca->result) ? '' : $ca->result;
441 $curr = DB_DataObject::factory('curr_symbol')->base();
443 'cust_custtype_id' => $this->sqlValue("fetchmetricvalue('DefaultCustType'::text)"),
444 'cust_salesrep_id' => $this->sqlValue("fetchmetricvalue('DefaultSalesRep'::text)"),
445 'cust_commprcnt' => 0,
446 'cust_creditrating' => $this->sqlValue("fetchmetrictext('SOCreditRate'::text)"),
447 'cust_active' => true,
449 'cust_backorder' => true, // must accept partial and backorder..
450 'cust_partialship' => true,
451 'cust_discntprcnt' => 0,
452 'cust_balmethod' =>'B',
454 'cust_ffshipto' => true, //
455 'cust_shipform_id' => $this->sqlValue("fetchmetricvalue('DefaultShipFormId'::text)"),
457 'cust_shipvia' => $this->sqlValue("fetchdefaultshipvia()"),
458 'cust_blanketpos' => false,
460 'cust_shipchrg_id' => -1,
461 'cust_creditstatus' => 'G',
462 'cust_comments' => '',
463 'cust_ffbillto' => true,
465 'cust_usespos' => false, // uses purchase orders'
467 'cust_autoupdatestatus' => false,
468 'cust_autoholdorders' => false,
470 //'cust_preferred_warehous_id' => -1, // default warehouse...
472 //'cust_cntct_id' => -1, /// created later by
473 //'cust_corrcntct_id' => -1,
474 'cust_taxzone_id' => $this->sqlValue("gettaxzoneid('NO TAX')"),
475 'cust_gracedays' => 0,
476 'cust_terms_id' => $this->sqlValue("fetchmetricvalue('DefaultTerms'::text)"),
477 'cust_curr_id' => $curr->pid(),//// currency
478 'cust_creditlmt_curr_id' => $this->sqlValue("getcurrid('HKD'::text)"),/// currency again?
480 'cust_subscribed' => true,
482 'cust_passwd' => $this->generatePassword(), /// ???? should this be here??
490 function initDatabase($roo)
492 if ($this->count()) {
495 $companies = DB_DataObject::factory('companies');
496 $enum = DB_DataObject::Factory('core_enum')->lookup('COMPTYPE', 'OWNER');
499 echo "SKIP - custinfo - create - missing core_enum = OWNER";
504 $companies = DB_DataObject::factory('core_company');
505 $companies->comptype_id = $enum;
506 if ($companies->count() != 1) {
507 echo "SKIP - custinfo - create - missing owner company";
510 $companies->find(true);
514 $this->setFrom(array(
515 'cust_name' => $companies->name,
516 'cust_number' => empty($companies->code) ? strtoupper(preg_replace('/[^a-z0-9]+/i', '', $companies->name)) : $companies->code,
518 $this->beforeInsert(array(), $roo);
524 function beforeInsert($req,$roo)
526 $defs = $this->defaults() ;
527 foreach($defs as $k=>$v) {
528 if (!isset($req[$k])) {
531 if (in_array($k, array( 'cust_creditlmt_curr_id', 'cust_curr_id')) && empty($r[$k])) {
536 if ($this->cust_creditlmt_curr_id != $this->cust_curr_id) {
537 $this->cust_creditlmt_curr_id = $this->cust_curr_id;
539 if (empty($this->cust_cntct_id)) {
540 $this->cust_cntct_id = $this->sqlValue('NULL');
542 if($this->cust_number){
543 if(!$this->custNumberDupeCheck()){
544 $roo->jerr("Customer code {$this->cust_number} already exists!");
547 if($this->cust_login_email){
548 if(!$this->loginEmailDupeCheck()){
549 $roo->jerr("Login Email {$this->cust_login_email} already exists!");
555 function beforeUpdate($old, $q, $roo)
557 if(empty($old->cust_passwd)){
558 $this->generatePassword(); // fix the existing costomers..
561 if ($old->cust_curr_id != $this->cust_curr_id) {
562 $this->cust_creditlmt_curr_id = $this->cust_curr_id;
564 if (empty($this->cust_cntct_id)) {
565 $this->cust_cntct_id = $this->sqlValue('NULL');
567 if($old->cust_number != $this->cust_number) {
568 if(!$this->custNumberDupeCheck()){
569 $roo->jerr("Customer code {$this->cust_number} already exists!");
572 if($old->cust_login_email != $this->cust_login_email) {
573 if(!$this->loginEmailDupeCheck()){
574 $roo->jerr("Login Email {$this->cust_login_email} already exists!");
579 function onInsert($req,$roo)
581 // update includes information on ship addresses.
583 // we need to sync this up with shiptoinfo..
584 $c = DB_DataObject::factory('custinfo');
585 $c->cust_name = $this->cust_name;
587 $roo->jerr('Customer name already exists!');
589 $c = DB_DataObject::factory('custinfo');
590 $c->cust_number = $this->cust_number;
592 $roo->jerr('Customer number already exists!');
596 if (isset($req['shiplist'])) {
597 $ar = explode(',', $req['shiplist']);
598 $this->updateShipList($ar);
601 if (isset($req['ipshead_id'])) {
602 $this->updatePriceList($req['ipshead_id']);
605 $this->updateCharass($req);
607 $this->updateCntct($roo);
611 function findInternal($int_name, $cur)
614 //DB_DataObject::DebugLevel(1);
615 $ve = $this->factory($this->tableName());
616 $ve->cust_curr_id = $cur->pid();
617 $ve->whereAdd(" charass_getvalue('C',
619 'INTERNALCOMPANY') = '{$this->escape($int_name)}'");
620 // fixme INTERNALCOMPANY must be added to contacts
621 $matches = $ve->count();
622 if (!$matches || $matches > 1) {
631 * create or return the default contact..
632 * if none exists.. try and find one..
633 * @return Pman_Xtuple_DataObjects_Cntct the contact..
635 function defaultContact($order = false)
637 if ($this->cust_cntct_id) {
638 return $this->cntct();
641 $order = array('ba', 'ca');
645 $crm = $this->crmacct();
646 $cnt = $this->cntct();
647 $cnt->cntct_crmacct_id = $crm->crmacct_id;
649 // we could be smarter and look for 'default *'
651 foreach($order as $pr) {
654 $c->whereAdd("cntct_number' like '{$pr}-%'");
658 $this->cust_cntct_id = $cnt->cntct_id;
665 // finally anybody else..
669 $this->cust_cntct_id = $cnt->cntct_id;
675 //create a dummy address..... = since there are no contacts that has to be created as well.
676 throw new Exception("no default contact");
679 public $cntct_addr_id; // int4(4)
680 public $cntct_first_name; // text(-1)
681 public $cntct_last_name; // text(-1)
682 public $cntct_honorific; // text(-1)
683 public $cntct_initials; // text(-1)
684 public $cntct_active; // bool(1) default_true
685 public $cntct_phone; // text(-1)
686 public $cntct_phone2; // text(-1)
687 public $cntct_fax; // text(-1)
688 public $cntct_email; // text(-1)
689 public $cntct_webaddr; // text(-1)
690 public $cntct_notes; // text(-1)
691 public $cntct_title; // text(-1)
692 public $cntct_number; // text(-1) not_null unique_key
693 public $cntct_middle; // text(-1)
694 public $cntct_suffix; // text(-1)
695 public $cntct_owner_username; // text(-1)
707 function updateShipList($contacts)
709 // find all the current shipping contacts.
710 //DB_DataObject::debugLevel(1);
711 $sh = DB_DataObject::factory('shiptoinfo');
712 $sh->shipto_cust_id= $this->cust_id;
713 $sh->shipto_active = true;
714 $exist = $sh->fetchAll();
719 $c = DB_DataObject::factory('cntct');
720 $c->whereAddIn('cntct_id', $contacts,'int');
721 $cnts = $c->fetchAll();
724 // insert if not referenced...
727 foreach($cnts as $c) {
732 if (!$sh->shipto_id) {
733 // then a shipinfo does not exist..
734 $sh = DB_DataObject::factory('shiptoinfo');
735 $sh = $sh->createFromCustomerContact($this, $c);
736 $used[] = $sh->shipto_id;
740 //if ($sh->shipto_active && $sh->shipto_active != 'f') {
743 // $used[] = $sh->shipto_id;
747 $sh->shipto_active = true;
748 $sh->shipto_name = $c->cntct_name;
750 $used[] = $sh->shipto_id;
752 // skip... - updating..
755 // look at exist, and see if we can delete unused items..
756 foreach($exist as $sh) {
757 if (in_array($sh->shipto_id, $used)) {
761 $sh->shipto_active = false;
771 $p = DB_DataObject::Factory('ipsass');
772 $p->ipsass_cust_id = $this->pid();
773 $old = $p->fetchAll();
778 $ipshead = DB_DataObject::Factory('ipshead');
779 $ipshead->get($old[0]->ipsass_ipshead_id);
784 function updatePriceList($ipshead)
787 if (empty($ipshead)) {
790 // get the current ones..
791 $p = DB_DataObject::Factory('ipsass');
792 $p->ipsass_cust_id = $this->pid();
793 $old = $p->fetchAll();
794 foreach($old as $o) {
795 if ($o->ipsass_ipshead_id != $ipshead) {
799 return; // got it and no change.. // does not handle multiple..
801 $p = DB_DataObject::Factory('ipsass');
802 $p->ipsass_cust_id = $this->pid();
803 $p->ipsass_ipshead_id = $ipshead;
807 function postListFilter($ar, $au, $q)
809 if(isset($q['_my_json'])){
813 require_once 'pear/System.php';
814 $tmpdir = System::mktemp("-d abitodocx");
815 $path = $tmpdir . '/Customers-' . $q['search']['_country'] . '-' . date('Y-m-d') . '.json';
816 header("Content-Disposition: attachment; filename=\"".basename($path)."\";" );
817 echo json_encode($ar);
820 if (isset($q['_with_lastyear_total'])) {
824 $always_display = DB_DataObject::factory('charass')->lookupIds('C', 'SALESFORECAST', 'always display');
826 foreach ($old_ar as $k => $v){
827 if(in_array($v['cust_id'], $always_display)){ // put 'always display' cust into the top list
829 array_unshift($ar, $old_ar[$k]);
833 $all_total = $this->totalSales($q['_charass_brand_value'],$q['_charass_group_value']);
835 $allcompanies = array(
837 'cust_name' => 'All Companies',
838 'lastyear_total' => $all_total,
843 array_unshift($ar,$allcompanies);
849 $top_total += $a['lastyear_total'];
854 'cust_name' => '----------Others----------',
855 'lastyear_total' => $all_total - $top_total,
856 'view_type' => 'others'
858 array_push($ar, $line);
859 array_unshift($ar, $allcompanies);
864 if(isset($q['_with_group_data'])){
867 $addBillAddress = array();
868 $addShipAddress = array();
870 $cols = array('address1', 'address2', 'address3', 'city', 'state', 'country');
872 foreach ($cols as $col){
873 if($a['cust_cohead_billto' . $col] != ''){
874 $addBillAddress[] = $a['cust_cohead_billto' . $col];
876 if($a['cust_cohead_shipto' . $col] != ''){
877 $addShipAddress[] = $a['cust_cohead_shipto' . $col];
880 $a['cust_bill_info'] = implode("\r\n", $addBillAddress);
881 $a['cust_ship_info'] = implode("\r\n", $addShipAddress);
890 function topCustomerIdsBySalesQty()
892 $c = DB_DataObject::factory('custinfo');
897 ROUND(COALESCE(SUM(invcitem_billed),0))
903 invcitem_invchead_id = invchead_id
907 invcitem_item_id = itemsite_item_id
910 invchead_cust_id = cust_id
912 extract(year from invchead_invcdate) = extract(year from NOW() - INTERVAL '1 YEAR')
914 itemsite_stocked = TRUE
918 $c->orderBy('lastyear_total DESC');
922 $total_sales = $this->totalSales();
925 if($total > ceil($total_sales * 0.8)){
928 $total += $c->lastyear_total;
929 $ids[] = $c->cust_id;
934 function totalSales($brand = '', $group = '')
936 $ic = DB_DataObject::factory('invcitem');
942 invcitem_invchead_id = invchead_id
946 invcitem_item_id = itemsite_item_id
950 ROUND(COALESCE(SUM(invcitem_billed),0)) as total_sales
953 extract(year from invchead_invcdate) = extract(year from NOW() - INTERVAL '1 YEAR')
955 itemsite_stocked = TRUE
958 $brand_ids = DB_DataObject::factory('charass')->lookupIds('I', 'BRAND', $brand);
959 $ic->whereAddIn('invcitem_item_id', $brand_ids, 'int');
962 $group_ids = DB_DataObject::factory('charass')->lookupIds('I', 'PRODUCTGROUP', $group);
963 $ic->whereAddIn('invcitem_item_id', $group_ids, 'int');
966 return $ic->total_sales;
969 function custNumberDupeCheck()
971 $custinfo = DB_DataObject::factory('custinfo');
973 $custinfo->cust_number = $this->cust_number;
975 $custinfo->whereAdd("
976 cust_number = '{$this->escape($this->cust_number)}'
979 if($custinfo->count()){
986 function loginEmailDupeCheck()
988 $custinfo = DB_DataObject::factory('custinfo');
989 $custinfo->whereAdd("
990 cust_login_email = '{$this->escape($this->cust_login_email)}'
992 if($custinfo->count()){
1000 function updateCharass($req)
1002 if (isset($req['cust_char_internalcompany'])) {
1003 // update the char...
1004 $ca = DB_DAtaObject::factory('charass');
1008 'INTERNALCOMPANY', '{$this->escape($req['cust_char_internalcompany'])}'
1013 if (isset($req['cust_char_salesforecast'])) {
1014 // update the char...
1015 $ca = DB_DAtaObject::factory('charass');
1019 'SALESFORECAST', '{$this->escape($req['cust_char_salesforecast'])}'
1024 if (isset($req['cust_char_au_post_accno'])) {
1025 // update the char...
1026 $ca = DB_DAtaObject::factory('charass');
1030 'AU-POST-ACCNO', '{$this->escape($req['cust_char_au_post_accno'])}'
1037 function filterTop()
1039 $top = $this->topCustomerIdsBySalesQty();
1040 $top = array_merge($top , DB_DataObject::factory('charass')->lookupIds('C', 'SALESFORECAST', 'always display'));
1041 $top = array_diff($top , DB_DataObject::factory('charass')->lookupIds('C', 'SALESFORECAST', 'hide'));
1047 function priceListCurrency($roo)
1049 $ipsass = DB_DataObject::Factory('ipsass');
1051 if (!$ipsass->get('ipsass_cust_id', $this->pid())){
1052 $roo->jerr("Customer {$this->cust_name} does not have a pricelist associated with it.");
1055 $ipshead = DB_DataObject::factory('ipshead');
1057 if(!$ipshead->get($ipsass->ipsass_ipshead_id)){
1058 $roo->jerr("Cound not find the pricelist for {$this->cust_name}");
1061 $curr = DB_DataObject::factory('curr_symbol');
1062 if(!$curr->get($ipshead->ipshead_curr_id)){
1063 $roo->jerr("Cound not find currency id : {$ipshead->ipshead_curr_id}");
1069 function checkPassword($val)
1072 if (substr($this->cust_passwd,0,1) == '$') {
1073 return crypt($val,$this->cust_passwd) == $this->cust_passwd ;
1075 // old style md5 passwords...- cant be used with courier....
1076 return md5($val) == $this->cust_passwd;
1079 function setPassword($value)
1082 while(strlen($salt)<9) {
1083 $salt.=chr(rand(64,126));
1086 $this->cust_passwd = crypt($value, '$1$'. $salt. '$');
1089 function generatePassword() // genearte a password (add set 'rawPasswd' to it's value)
1091 require_once 'Text/Password.php';
1092 $this->rawPasswd = strtr(ucfirst(Text_Password::create(5)).ucfirst(Text_Password::create(5)), array(
1093 "a"=>"4", "e"=>"3", "i"=>"1", "o"=>"0", "s"=>"5", "t"=>"7"));
1094 $this->setPassword($this->rawPasswd);
1095 return $this->rawPasswd;
1098 function sendMail($roo)
1100 if(empty($this->type)){
1104 $md5 = md5(date('r', time()));
1105 $e = $roo->addEvent($this->type, $this, $md5);
1108 'template' => $this->type,
1112 'serverName' => $_SERVER['SERVER_NAME'],
1113 'baseURL' => $roo->baseURL
1116 $sent = DB_DataObject::factory('core_email')->send($content);
1118 if(!is_object($sent)){
1126 function updateCntct($roo)
1128 if(empty($this->cust_cntct_id)){
1132 $cntct = DB_DataObject::factory('cntct');
1133 $cntct->get($this->cust_cntct_id);
1134 $old = clone ($cntct);
1136 $cntct->cntct_email = $this->cust_login_email;
1137 $cntct->update($old);
1140 function myOrderDetails($type, $offset, $limit)
1144 $cohead = DB_DataObject::factory('cohead');
1147 cobmisc AS join_cobmisc
1149 join_cobmisc.cobmisc_cohead_id = cohead_id AND cobmisc_posted = true
1151 invchead AS join_invchead
1153 join_invchead.invchead_id = join_cobmisc.cobmisc_invchead_id
1155 aropen AS join_aropen
1157 join_aropen.aropen_doctype = 'I' AND join_aropen.aropen_docnumber = join_invchead.invchead_invcnumber
1159 shiphead AS join_shiphead
1161 join_shiphead.shiphead_order_id = cohead_id AND join_shiphead.shiphead_shipdate IS NOT NULL AND join_shiphead.shiphead_shipped
1163 $cohead->selectAdd("
1164 calcsalesorderamt(cohead_id::integer) AS amount,
1165 CASE WHEN (join_cobmisc.cobmisc_id IS NULL OR (join_aropen.aropen_amount - join_aropen.aropen_paid) > 0) THEN
1167 WHEN join_shiphead.shiphead_id IS NOT NULL THEN
1168 join_shiphead.shiphead_delivery_note
1175 cohead_cust_id = {$this->pid()}
1177 cohead_status != 'X'
1180 $cohead->orderBy('cohead_number DESC');
1182 if($type == 'History'){
1184 cohead_orderdate < NOW()::date - INTERVAL '7 DAY'
1186 join_cobmisc.cobmisc_id IS NOT NULL
1188 join_aropen.aropen_amount - join_aropen.aropen_paid = 0
1190 join_shiphead.shiphead_id IS NOT NULL
1194 $count = ceil($cohead->count() / $limit);
1195 $ret['count'] = (!$count) ? 1 : $count;
1198 $cohead->limit($offset, $limit);
1200 $ret['details'] = $cohead->fetchAll();
1205 function myOrderSummary()
1207 $cohead = DB_DataObject::factory('cohead');
1209 cohead_cust_id = {$this->pid()}
1211 cohead_status != 'X'
1223 while ($cohead->fetch()){
1224 $c = clone ($cohead);
1226 $cobmisc = DB_DataObject::factory('cobmisc');
1227 $cobmisc->cobmisc_cohead_id = $c->pid();
1228 $cobmisc->cobmisc_posted = 1;
1230 if(!$cobmisc->find(true)){
1231 $ret['pending'] = $ret['pending'] + 1;
1235 $invoice = $cobmisc->invchead();
1236 $aropen = $invoice->aropen();
1238 $unpaid = ($aropen->aropen_amount - $aropen->aropen_paid) * 1;
1241 $ret['pending'] = $ret['pending'] + 1;
1245 $shiphead = DB_DataObject::factory('shiphead');
1246 $shiphead->whereAdd("
1247 shiphead_order_id = {$cohead->pid()}
1249 shiphead_shipdate IS NOT NULL
1254 if(!$shiphead->count()){
1255 $ret['processing'] = $ret['processing'] + 1;
1259 $ret['processed'] = $ret['processed'] + 1;
1265 function genNumber($prefix = 'CUST')
1267 if(!empty($this->cust_name)){
1273 $x = DB_DataObject::Factory('custinfo');
1276 while ($x->get('cust_name', $l . (!$suf ? '' : '-' . $suf))) {
1277 $x = DB_DataObject::Factory('custinfo');
1281 $this->cust_name = $l . (!$suf ? '' : '-' . $suf);
1282 $this->cust_number = $l . (!$suf ? '' : '-' . $suf);
1287 function getEmailFrom()
1289 return $this->cust_login_email;
1291 // if (empty($this->cust_name)) {
1292 // return $this->cust_login_email;
1294 // return '"' . addslashes($this->cust_name) . '" <' . $this->cust_login_email . '>';
1297 function nameColumn()
1302 function emailColumn()
1304 return 'cust_login_email';